From cc7ce9883312ee643bed61ef947b8f75bffab7a3 Mon Sep 17 00:00:00 2001 From: Luke Edwards Date: Tue, 5 Oct 2021 09:16:09 -0700 Subject: [PATCH] feat: support ".mts" and ".cts" extensions (#3) * chore: bump esbuild version * feat: add ".cts" and ".mts" as default extns * chore: add "mts" and "cts" fixtures; - typescript file uses "mjs" and "cjs" imports - javascript files use real "mts" and "cts" imports * chore(ci): also run typescript test w/ --require hook --- .github/workflows/ci.yml | 7 +++++-- docs/configuration.md | 2 ++ package.json | 2 +- src/utils.ts | 2 ++ test/config/index.ts | 14 ++++++++++++++ test/fixtures/utils.cts | 3 +++ test/fixtures/utils.mts | 3 +++ test/index.js | 22 +++++++++++++++++++--- test/index.mjs | 18 ++++++++++++++++-- 9 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/utils.cts create mode 100644 test/fixtures/utils.mts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d255b9..6e596d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,8 +36,11 @@ jobs: - name: Tests <~ ESM run: node --loader ./loader.mjs test/index.mjs + - name: Tests <~ ESM <~ TypeScript + run: node --loader ./loader.mjs test/config/index.ts --tsmconfig test/config/tsm.js + - name: Tests <~ CommonJS run: node -r ./require.js test/index.js - - name: Tests <~ TS w/ Config - run: node --loader ./loader.mjs test/config/index.ts --tsmconfig test/config/tsm.js + - name: Tests <~ CommonJS <~ TypeScript + run: node -r ./require.js test/config/index.ts --tsmconfig test/config/tsm.js diff --git a/docs/configuration.md b/docs/configuration.md index fb717d3..d9edf84 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -29,6 +29,8 @@ Additionally, tsm defines a few extensions by default, each of which is assigned let config = { '.jsx': { ...options, loader: 'jsx' }, '.tsx': { ...options, loader: 'tsx' }, + '.mts': { ...options, loader: 'ts' }, + '.cts': { ...options, loader: 'ts' }, '.ts': { ...options, loader: 'ts' }, } ``` diff --git a/package.json b/package.json index b72a604..f46a955 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "types": "tsc" }, "dependencies": { - "esbuild": "^0.13.3" + "esbuild": "^0.13.4" }, "devDependencies": { "@types/node": "16.10.2", diff --git a/src/utils.ts b/src/utils.ts index bd76880..349a6c0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -43,8 +43,10 @@ exports.$finalize = function (env: Defaults, custom?: tsm.ConfigFile): tsm.Confi } let config: tsm.Config = { + '.mts': { ...base, loader: 'ts' }, '.jsx': { ...base, loader: 'jsx' }, '.tsx': { ...base, loader: 'tsx' }, + '.cts': { ...base, loader: 'ts' }, '.ts': { ...base, loader: 'ts' }, }; diff --git a/test/config/index.ts b/test/config/index.ts index 781fccc..c0d4f70 100644 --- a/test/config/index.ts +++ b/test/config/index.ts @@ -2,6 +2,10 @@ import * as assert from 'assert'; // NOTE: doesn't actually exist yet import * as js from '../fixtures/math.js'; +// @ts-ignore - cannot find types +import * as mjs from '../fixtures/utils.mjs'; +// @ts-ignore - cannot find types +import * as cjs from '../fixtures/utils.cjs'; // NOTE: avoid need for syntheticDefault + analysis import * as data from '../fixtures/data.json'; @@ -17,4 +21,14 @@ assert.equal(typeof js.div, 'function', 'JS :: typeof :: div'); assert.equal(typeof js.mul, 'function', 'JS :: typeof :: mul'); assert.equal(js.foobar, 3, 'JS :: value :: foobar'); +// NOTE: raw MJS missing +assert.equal(typeof mjs, 'object', 'MJS :: typeof'); +assert.equal(typeof mjs.capitalize, 'function', 'MJS :: typeof :: capitalize'); +assert.equal(mjs.capitalize('hello'), 'Hello', 'MJS :: value :: capitalize'); + +// NOTE: raw CJS missing +assert.equal(typeof cjs, 'object', 'CJS :: typeof'); +assert.equal(typeof cjs.dashify, 'function', 'CJS :: typeof :: dashify'); +assert.equal(cjs.dashify('FooBar'), 'foo-bar', 'CJS :: value :: dashify'); + console.log('DONE~!'); diff --git a/test/fixtures/utils.cts b/test/fixtures/utils.cts new file mode 100644 index 0000000..f265d94 --- /dev/null +++ b/test/fixtures/utils.cts @@ -0,0 +1,3 @@ +export function dashify(str: string): string { + return str.replace(/([a-zA-Z])(?=[A-Z\d])/g, '$1-').toLowerCase(); +} diff --git a/test/fixtures/utils.mts b/test/fixtures/utils.mts new file mode 100644 index 0000000..11db639 --- /dev/null +++ b/test/fixtures/utils.mts @@ -0,0 +1,3 @@ +export function capitalize(str: string): string { + return str[0].toUpperCase() + str.substring(1); +} diff --git a/test/index.js b/test/index.js index d484742..abbb89c 100644 --- a/test/index.js +++ b/test/index.js @@ -1,10 +1,16 @@ // @ts-check const assert = require('assert'); -const jsx = require('./fixtures/App1'); +const jsx = require('./fixtures/App1.jsx'); const json = require('./fixtures/data.json'); -const tsx = require('./fixtures/App2'); -const ts = require('./fixtures/math'); +// @ts-ignore – prefers extensionless +const tsx = require('./fixtures/App2.tsx'); +// @ts-ignore – prefers extensionless +const ts = require('./fixtures/math.ts'); +// @ts-ignore – prefers extensionless +const mts = require('./fixtures/utils.mts'); +// @ts-ignore – prefers extensionless +const cts = require('./fixtures/utils.cts'); const props = { foo: 'bar' @@ -39,4 +45,14 @@ assert.equal(typeof ts.div, 'function', 'TS :: typeof :: div'); assert.equal(typeof ts.mul, 'function', 'TS :: typeof :: mul'); assert.equal(ts.foobar, 3, 'TS :: value :: foobar'); +assert(mts, 'MTS :: typeof'); +assert.equal(typeof mts, 'object', 'MTS :: typeof'); +assert.equal(typeof mts.capitalize, 'function', 'MTS :: typeof :: capitalize'); +assert.equal(mts.capitalize('hello'), 'Hello', 'MTS :: value :: capitalize'); + +assert(cts, 'CTS :: typeof'); +assert.equal(typeof cts, 'object', 'CTS :: typeof'); +assert.equal(typeof cts.dashify, 'function', 'CTS :: typeof :: dashify'); +assert.equal(cts.dashify('FooBar'), 'foo-bar', 'CTS :: value :: dashify'); + console.log('DONE~!'); diff --git a/test/index.mjs b/test/index.mjs index 57042e5..cf7a521 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -3,8 +3,14 @@ import assert from 'assert'; import jsx from './fixtures/App1'; import json from './fixtures/data.json'; -import * as ts from './fixtures/math'; -import tsx from './fixtures/App2'; +// @ts-ignore – expects definitions +import * as mts from './fixtures/utils.mts'; +// @ts-ignore – expects definitions +import * as cts from './fixtures/utils.cts'; +// @ts-ignore – prefers extensionless +import * as ts from './fixtures/math.ts'; +// @ts-ignore – prefers extensionless +import tsx from './fixtures/App2.tsx'; const props = { foo: 'bar' @@ -39,4 +45,12 @@ assert.equal(typeof ts.div, 'function', 'TS :: typeof :: div'); assert.equal(typeof ts.mul, 'function', 'TS :: typeof :: mul'); assert.equal(ts.foobar, 3, 'TS :: value :: foobar'); +assert.equal(typeof mts, 'object', 'MTS :: typeof'); +assert.equal(typeof mts.capitalize, 'function', 'MTS :: typeof :: capitalize'); +assert.equal(mts.capitalize('hello'), 'Hello', 'MTS :: value :: capitalize'); + +assert.equal(typeof cts, 'object', 'CTS :: typeof'); +assert.equal(typeof cts.dashify, 'function', 'CTS :: typeof :: dashify'); +assert.equal(cts.dashify('FooBar'), 'foo-bar', 'CTS :: value :: dashify'); + console.log('DONE~!');