I have a typescript project that is build and distributed as es6 modules, so I have a tsconfig which sets "module": "es6".
When using ts-node in this project it doesn't work, (ts-)node throws SyntaxErrors since it doesn't support es6 modules yet. (I work around this by setting the TS_NODE_COMPILER_OPTIONS env variable)
But i'm wondering if ts-node should not just always 'override' this settings from a tsconfig file and always use commonjs...
Maybe. ES6 modules might be supported in node.js natively one day so deviating from spec will cause issues. Happy to consider it though, but my feeling is no as the goals of this project is to have it act like tsc + node.
Perhaps a way to override the setting without using environment variables, like a ts-node section in package.json or a custom property in tsconfig.json.
See https://github.com/TypeStrong/ts-node/issues/4. I haven't really done it because I haven't had the need and don't quite understand how it'd work for others yet.
The way I do it, is setting the env in package.json/npm 'run scripts' section. The requires ugly double escaping, but it works as a (hopefully temporary) workaround.
Example for other people who encounter is problem, a line in from my package.json, inside the scripts section:
"ts-node": "TS_NODE_COMPILER_OPTIONS=\"{\\\"module\\\":\\\"commonjs\\\"}\" ts-node",
But my question is, should ts-node even allow configuration that doesn't work. Is there any use-case where you would want ts-node outputting a module format that isn't supported by node (only commonjs and umd output work now)?
And when node start supporting es6 modules, this would require checking the node version.
The other option is just documenting this problem and the possible workarounds.... and wait for es6 support in node to make this problem go away.
What if someone wants ES6 module output because they use it with Babel transpilation or something similar? I'd rather not enforce a specific configuration, as it's up to people and configuration for that.
Thanks for this workaround, I finally ended up with
"mocha": "node node_modules/mocha/bin/mocha --opts .mocharc",
"test:ci": "set TS_NODE_COMPILER_OPTIONS={\"module\":\"commonjs\"} && npm run mocha",
This works on Windows. No luck on OSX so far.
Any news? @MrCrimp suggestion works but it isn't ideal, and it doesn't seem to work on other operating systems. I tried with cross-env but it also doesn't work due to a bug when sending JSON (https://github.com/kentcdodds/cross-env/issues/30)
@Apidcloud What news do you expect? I have no intention on changing the behaviour, I'd suggest using multiple tsconfig.json files with extends if it's something you need and point to whichever using --project.
Using multiple tsconfig can do the trick, but either way, my question was referring to whether you are planning on supporting ES6 modules or not.
Also, @MrCrimp and @jorrit-wehelp, check this thread. It's not ideal, but it's possible to have it running on OSX, Linux and Windows with slightly different test scripts.
I am not going to do anything to support ES6 modules. I'm not really sure what that would mean for ts-node. It's a node.js concern and an extremely non-trivial feature for the core team to implement. When node.js supports it, ts-node would also support it - until then you should be emitting CommonJS modules which is what support in TypeScript looks like today (you can already use ES6 modules, just remember to transpile them).
I understand 馃憤 and exactly, I am using ES6 modules for the normal build process and transpiling them to ES5 using babel afterwards (I need both versions). For unit testing I'm changing it (with ts-node's environment variable) to commonjs.
Thanks again!
I just found this handy -O flag: ts-node -O '{"lib": [ "es2015" ]}' main.ts
Just want to add on to what @collheesi mentioned.
If you want to use ESmodules (_AKA import syntax_), to test quick scripts, overwrite the default TS_NODE_COMPILER_OPTIONS pass the -O flag with values to overwrite:
npx ts-node -O '{"module": "commonjs"}' my-file.ts
//If your using very low versions of node or browser, set the `target` option lower
npx ts-node -O '{"module": "commonjs", "target": "es5"}'
import { spawn } from 'child_process';
const child = spawn('pwd');
child.on('exit', (code: Number, signal:string):void => {
console.log(`child process exited with code ${code} and signal ${signal}`);
});
You may ask yourself what/where are those options I'm passing coming from? These key-values are options you pass to [ts-config.json](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) 's "compilerOptions" section.
This is all on the README of this repo, but .. like most I overlooked it and wanted to point it out again. Love this -O flag for ts-node, btw
Most helpful comment
Thanks for this workaround, I finally ended up with
This works on Windows. No luck on OSX so far.