diff --git a/package-lock.json b/package-lock.json index f8cf33b..fe6f7c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@mdn/browser-compat-data": "^4.0.0", "@web/dev-server-core": "^0.7.0", "esbuild": "^0.19.11", + "get-tsconfig": "^4.7.2", "parse5": "^6.0.1", "ua-parser-js": "^1.0.33" }, @@ -2322,6 +2323,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -3505,6 +3517,14 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", diff --git a/package.json b/package.json index becd74e..b53a19a 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@mdn/browser-compat-data": "^4.0.0", "@web/dev-server-core": "^0.7.0", "esbuild": "^0.19.11", + "get-tsconfig": "^4.7.2", "parse5": "^6.0.1", "ua-parser-js": "^1.0.33" }, diff --git a/src/EsbuildPlugin.ts b/src/EsbuildPlugin.ts index 5143101..28a2d78 100644 --- a/src/EsbuildPlugin.ts +++ b/src/EsbuildPlugin.ts @@ -18,6 +18,7 @@ import { setTextContent, } from '@web/dev-server-core/dist/dom5'; import { parse as parseHtml, serialize as serializeHtml } from 'parse5'; +import { parseTsconfig } from 'get-tsconfig'; import { getEsbuildTarget } from './getEsbuildTarget.js'; @@ -61,7 +62,8 @@ export class EsbuildPlugin implements Plugin { this.config = config; this.logger = logger; if (this.esbuildConfig.tsconfig) { - this.tsconfigRaw = await promisify(fs.readFile)(this.esbuildConfig.tsconfig, 'utf8'); + const parsedTsconfig = await parseTsconfig(this.esbuildConfig.tsconfig); + this.tsconfigRaw = JSON.stringify(parsedTsconfig); } } diff --git a/test/fixture/tsconfig-with-experimental-decorators-parent.json b/test/fixture/tsconfig-with-experimental-decorators-parent.json new file mode 100644 index 0000000..7fab824 --- /dev/null +++ b/test/fixture/tsconfig-with-experimental-decorators-parent.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig-with-experimental-decorators.json" +} diff --git a/test/ts.test.ts b/test/ts.test.ts index 1049061..70b423b 100644 --- a/test/ts.test.ts +++ b/test/ts.test.ts @@ -104,6 +104,61 @@ class Bar { } }); + it('transforms TS decorators with parent tsconfig', async () => { + const { server, host } = await createTestServer({ + rootDir: __dirname, + plugins: [ + { + name: 'test', + serve(context) { + if (context.path === '/foo.ts') { + return ` +@foo +class Bar { + @prop + x = 'y'; +}`; + } + }, + }, + esbuildPlugin({ + ts: true, + tsconfig: path.join( + __dirname, + 'fixture', + 'tsconfig-with-experimental-decorators-parent.json', + ), + }), + ], + }); + + try { + const response = await fetch(`${host}/foo.ts`); + const text = await response.text(); + + expect(response.status).to.equal(200); + expect(response.headers.get('content-type')).to.equal( + 'application/javascript; charset=utf-8', + ); + expectIncludes(text, '__decorate'); + expectIncludes(text, '__publicField(this, "x", "y");'); + expectIncludes( + text, + `__decorateClass([ + prop +], Bar.prototype, "x", 2);`, + ); + expectIncludes( + text, + `Bar = __decorateClass([ + foo +], Bar);`, + ); + } finally { + server.stop(); + } + }); + it('resolves relative ending with .js to .ts files', async () => { const { server, host } = await createTestServer({ rootDir: path.join(__dirname, 'fixture'),