web
web copied to clipboard
[@web/dev-server-esbuild] does not read tsconfig.json
As far as I can tell, the ESBuild plugin does not look at tsconfig.json.
It uses the ESBuild's Transform API, which would require the plugin to explicitly pass the contents of the tsconfig.json
file via the tsconfigRaw option.
So far not reading the tsconfig.json hasn't presented any significant problems for me, but the fact that my changes to that file had no effect on web-dev-server was confusing. I would suggest either documenting the fact that the tsconfig.json file is ignored or adding an option to specify the path to the tsconfig.json file.
If either of those sounds good, or you have some other idea, I'm happy to create a PR.
Adding an option to specify the path would be a good idea.
I agree. We would need this to work, because we're using this within a monorepo, and specifying path aliases would be very useful. Thanks
@kobleistvan Would it be helpful if there was an option to automatically find the tsconfig file for each .ts file (using the same algorithm as TypeScript itself)?
That's my ultimate goal. I started with specifying the path to a single tsconfig.json because I didn't want to do too much in one PR (and there are cases when I want to point to a specific config).
@pmcelhaney In our application, we have a 'base' tsconfig in the monorepo root, and some packages have their own tsconfig file which extends the one from the root. So it would be great if perhaps the wtr command itself could take as an additional argument the path to a specific tsconfig file (and take into consideration the internal 'extends' key's value).
@pmcelhaney FYI, I worked around my issue via: `import { fromRollup } from '@web/dev-server-rollup'; import tsConfigPaths from 'rollup-plugin-tsconfig-paths';
const tsPaths = fromRollup(tsConfigPaths.default);
// ...
plugins: [ tsPaths({}), esbuildPlugin({ ts: true }), ], `
So basically there's a rollup plugin to overcome the path issues, and the fromRollup makes it so that I can use it here. Would be nice if there would be native support though (i.e. for other tsConfig configs)
Cheers
So far not reading the tsconfig.json hasn't presented any significant problems for me
One example for this being useful is the importsNotUsedAsValues
compilerOption. This option is supposed to fix the need for duplicate import statements when importing a module with both a type export and side-effects, like defining a custom-element.
Without this option, typescript strips all import statements, that only import types. This also gets rid off any side-effects that would happen during the import, see https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues .
Starting in v14, esbuild now aligns with behavior of tsc, see https://github.com/evanw/esbuild/releases/tag/v0.14.0 , so by default import-statements in typescript file often have to be listed twice, once for the type and once as a bare import to cause side-effects.
Passing the tsconfig with this option set to preserve
would fix the duplication.
I saw the MR for this being merged, but no new release for this plugin. Is there an estimate on when the next release is gonna happen?
This problem causes inconsistencies for some Typescript features (like decorators) in tests. I had a problem (explained in #1963) and returning back to v0.2.16 fixed the issue. I hope v0.3.1 will arrive soon with a fix for this.
Does anyone know what is the procedure for releases?
I just found this issue after a of of investigation of some problem I experienced in my project.
I'm happy that tsconfig can be specified since https://github.com/modernweb-dev/web/pull/1922 and specifying it resolved the problem I had, but I think that when ts
is set to true
, then @web/dev-server-esbuild
should try to find a tsconfig.json
. I'm not creating a new issue, because name of this one exactly describes what I wanted to write. Maybe but for "does not automatically read" part :)
Problem I had was that @web/dev-server-esbuild
compiles to esnext
if
- compiled module is loaded with latest version of browser (btw:
@mdn/browser-compat-data
is already 5.2.31 when I write this comment, where@web/dev-server-esbuild
is locked at^4.0.0
so not actually "latest version that exists", but rather "what it things is the latest version"), and - plugin is given no explicit
target
(my only config was{ts: true}
)
In my case it caused property decorated with a Lit decorator @query
,
@query('.something')
foo;
which in compiled code becomes:
__decorateClass([
query(".something")
], MyClass.prototype, "foo", 2);
being shadowed with an empty initializer:
foo;
(I'm aware it's a thin ice to use esbuild when Lit recommends using decorators in TS ina certain way)
Once pointed path to my tsconfig
, problem went away: the field initializer is not longer emitted.
@jrencz I agree. I figured adding a config option would be easier to "sell" to the maintainers and is probably necessary in some cases anyway. All that remains now is default that option to the location of the automatically found tsconfig.json
file (if one exists).
Per the TypeScript docs:
... the compiler searches for the tsconfig.json file starting in the current directory and continuing up the parent directory chain.
I don't have the bandwidth right now so I'll leave it open for anyone else who wants to create a pull request.
Hello there guys!
Any solution to namespace problem with esbuild and testing library ?
I have a component called flights.component.ts
I have a test which just imports the lit html web component import './flights.component
My test looks as follows
import './flights.component';
it('Should create admin-flights element', () => {
document.createElement('admin-flights');
});
I have the following configuration inside web-test-runner.config.mjs
import { esbuildPlugin } from '@web/dev-server-esbuild';
import { legacyPlugin } from '@web/dev-server-legacy';
import { fileURLToPath } from 'url';
export default {
files: ['src/**/*.spec.ts'],
nodeResolve: true,
watch: true,
concurrency: 10,
plugins: [
esbuildPlugin({ ts: true, tsconfig: fileURLToPath(new URL('./tsconfig.json', import.meta.url)), target: 'auto' }),
// make sure this plugin is always last
legacyPlugin({
polyfills: {
webcomponents: true,
// Inject lit's polyfill-support module into test files, which is required
// for interfacing with the webcomponents polyfills
custom: [
{
name: 'lit-polyfill-support',
path: 'node_modules/lit/polyfill-support.js',
test: "!('attachShadow' in Element.prototype)",
module: false,
},
],
},
}),
],
};
When i run the tests i got an error that it cannot resolve import @core/services
❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.
Error while transforming src/app/portals/admin/flights/flights.component.ts: Could not resolve import "@core/services".
10 | return result;
11 | };
> 12 | import { Api } from "@core/services";
| ^
13 | import { Component } from "@rhtml/component";
14 | import { FlexLayout } from "@rhtml/modifiers";
15 | import { Container } from "@rxdi/core";
Chrome: |██████████████████████████████| 1/1 test files | 0 passed, 0 failed
Finished running tests, watching for file changes...
In my tsconfig i have the following paths specified
"paths": {
"@shared/*": [
"app/shared/*"
],
"@introspection/*": [
"app/@introspection/*"
],
"@core/*": [
"app/core/*"
],
"@assets/*": [
"assets/*"
],
"~/*": [
"app/*"
]
}
I was assuming that since i have defined tsconfig
property and import the configuration inside esbuild plugin it will automatically resolve my paths but unfortunate this does not happen.
Any idea how i can manage to add my paths from tsconfig to esbuild ?
For my regular starting the application i am using babel to convert these paths to appropriate imports but inside web testing runner i cannot make it to work...
@Stradivario take a look at rollup-plugin-typescript-paths
I use it and it does the job
@kobleistvan and possibly @pmcelhaney is the test case I added here what you were referring to?
@jrencz how does one use rollup-plugin-typescript-paths
in wtr? I added typescriptPaths
to plugins but it just throws tons of Could not resolve import
errors.
Edit:
Figured it out. I needed the following configuration:
import {fromRollup} from '@web/dev-server-rollup';
import {typescriptPaths} from 'rollup-plugin-typescript-paths';
import {esbuildPlugin} from '@web/dev-server-esbuild';
export default {
plugins: [
fromRollup(typescriptPaths)({
preserveExtensions: true,
absolute: false,
transform(path) {
return '/' + path;
},
}),
esbuildPlugin({ts: true}),
],
}
All of the typescriptPaths
options provided above were necessary (for me at least).
@electrovir you need to pass the tsconfig part next to ts:true
in esbuild
Ah, thanks! I was able to get this working by specifying the tsconfig option to esbuildPlugin as now documented:
import { fileURLToPath } from 'url';
esbuildPlugin({
ts: true,
tsconfig: fileURLToPath(new URL('./tsconfig.json', import.meta.url)),
});
-- https://modern-web.dev/docs/dev-server/plugins/esbuild/
I also had to add "useDefineForClassFields": false
below "experimentalDecorators": true
in my tsconfig.json file as now documented by lit: https://lit.dev/docs/components/decorators/#decorators-typescript