enable serve with esbuild
Command
serve
Description
with the new application builder, you build using esbuild but serve using vite we are having a problem after trying to migrate to the new application builder and it only happen when we deploy but not when we serve it locally (trying to read something of undefined error) I know there is a --watch option for build, but it doesn't serve and we have a proxy configuration so trying to make it work using watch is complicated and it shouldn't be
Describe the solution you'd like
during serve to have option --builder which can be esbuild, I imagine it will be slower but it will be very beneficial to debug errors related to esbuild at least during the migration phase till the webpack support is dropped and everyone is using esbuild
Describe alternatives you've considered
another approach is for the build command to have option --serve and --proxy options it doesn't need to have the auto refresh and all of the features that serve has, just basic serving of the application
During ng serve vite is used soley as a web server, under the hood esbuild is still used to build and bundle the application code.
Does the error occur when using ng serve --configuration production?
we are using nx not ng, and it doesn't have production in the configuration for serve can you give me the list of the configuration that I should change?
FYI I found the problem finally
this.autoTable = await import('jspdf-autotable').then((library) => library.default);
here for some reason now library.default doesn't return the function that is exported, but the object, so I need to add another .default
this.autoTable = await import('jspdf-autotable').then(
(library) =>
(
library.default as unknown as {
default: (pdf: jsPDFDocument, options: UserOptions) => void;
}
).default,
);
but because of typing error I need to write the typing myself
Below is the configuration for server in production
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "<project-name≥:build:production"
},
"development": {
"buildTarget": "<project-name≥:build:development"
}
},
"defaultConfiguration": "development"
},
Below is the configuration for server in production
"serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "buildTarget": "<project-name≥:build:production" }, "development": { "buildTarget": "<project-name≥:build:development" } }, "defaultConfiguration": "development" },
no the error doesn't exist here I will try to reproduce it in a new Angular 17 project and share it
here is a reproduce for the problem
https://github.com/robertIsaac/jspdf-autotable-error-reprod
on ng serve and ng serve --configuration production it show function which is expected
but if you run ng b then npx serve .\dist\jspdf-autotable-error-reprod\browser\ it will show object which what causes the problem
you can also take a look at the console to see what exactly is autoTable
beside the new feature, should I open a bug for that here or in esbuild? or is it working as expected with esbuild?
This is expected behavior. You can read more about the error prone nature of default exports and CommonJS libraries here: https://esbuild.github.io/content-types/#default-interop
The jspdf-autotable package does have an ESM variant of the code that is published inside the package. Many packages use exports conditions to allow bundlers to automatically pick the appropriate code. However, this package is setup in a way that requires manually opting in to its usage via an import to jspdf-autotable/es. Using this import should alleviate the problem. The ESM code is also roughly 10KB smaller as well.
This is expected behavior. You can read more about the error prone nature of default exports and CommonJS libraries here: https://esbuild.github.io/content-types/#default-interop The
jspdf-autotablepackage does have an ESM variant of the code that is published inside the package. Many packages useexportsconditions to allow bundlers to automatically pick the appropriate code. However, this package is setup in a way that requires manually opting in to its usage via an import tojspdf-autotable/es. Using this import should alleviate the problem. The ESM code is also roughly 10KB smaller as well.
This a great solution, but I have a question, why the import behavior is different in serve than build? Can there be more diverge in the code and find unexpected bugs when I build or it only affects the commonjs libraries?
It differs because Vite adjusts the imports of CommonJS (CJS) modules to directly expose the default. You can find more details at: https://github.com/vitejs/vite/blob/947aa53bb8ea60ce03a207421a6e7a4117385e58/packages/vite/src/node/plugins/importAnalysis.ts#L873
Regarding divergences, a development app aims to closely mimic a production application, but it's not an exact replica. When building for production, factors such as dead-code elimination and side-effectful code can alter the app's behavior. However, such cases are relatively uncommon.
This issue is being closed as the implementation of a different development server, specifically esbuild serve, is not currently not in the roadmap.
This is expected behavior. You can read more about the error prone nature of default exports and CommonJS libraries here: https://esbuild.github.io/content-types/#default-interop The
jspdf-autotablepackage does have an ESM variant of the code that is published inside the package. Many packages useexportsconditions to allow bundlers to automatically pick the appropriate code. However, this package is setup in a way that requires manually opting in to its usage via an import tojspdf-autotable/es. Using this import should alleviate the problem. The ESM code is also roughly 10KB smaller as well.
hi @clydin
jspdf-autotable/es doesn't exist
which version of jspdf-autotable are you talking about?
@robertIsaac, the ./es is defined as an entry-point through the package exports. See: https://unpkg.com/browse/[email protected]/package.json
it doesn't work still
- Building...X [ERROR] TS2307: Cannot find module 'jspdf-autotable/es' or its corresponding type declarations. [plugin angular-compiler]
packages/web/src/app/widgets/export/builders/pdf-file-builder.ts:73:34:
73 │ this.autoTable = await import('jspdf-autotable/es').then(
@alan-agius4 @clydin I have updated the repo https://github.com/robertIsaac/jspdf-autotable-error-reprod to include the latest version of jspdf-autotable and trying to use jspdf-autotable/es
if I'm doing something wrong please let me know
@robertIsaac looks like you are using an version 3.5.23 of jspdf-autotable which does not expose /es as an entry-point.
See: https://github.com/robertIsaac/jspdf-autotable-error-reprod/blob/c0c1e960e5b9d11918534d9ec8d4bc6e7c8df484/package-lock.json#L7683-L7690
I'm sorry I forget to push
So for package exports to be resolved, the module and resolution options in TypeScript config need to be set to Node16 or NodeNext. This however would break other things.
As a workaround could ignore the TS error by doing the following;
// @ts-expect-error
this.autoTable = await import('jspdf-autotable/es').then((library) => library.default);
I would suggest that you however an issue with the author of jspdf-autotable so that they implement a package export option which is transparent for the consumer and the bundler/runtime can pick up the right variant of the code.
"exports": {
".": {
"types": "./dist/index.d.ts",
+ "import": "./dist/jspdf.plugin.autotable.mjs",
"default": "./dist/jspdf.plugin.autotable.js"
},
"./es": { // They could potentially deprecate this.
"types": "./dist/index.d.ts",
"default": "./dist/jspdf.plugin.autotable.mjs"
}
},
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.