New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support output.libraryTarget: 'module' #2933
Comments
I definitely see the merit in this. @sokra I don't think we have a way already to export vanilla es2015 / es modules. I think that maybe this can be part of the rollup story (module combining/(and this splitting exporting)). |
Is there anything I can do to help with that? Can I tackle this problem myself as someone who is unfamiliar with webpacks code base? Or is this a rabbit hole into the guts of webpack? :) |
For a feature like this we should write up the design for the feature. Questions I think should be answerered first:
|
Once we have the behavior designed then you can go straight into adding the test cases. |
Seems to be like big step. Could we introduce some workaround in the meantime? Like emitting plain non-bundled commonjs modules without Use case is similar. I want to build a project with webpacks powerful loaders and I want to output some sort of modules without webpack specific logic, so that they can be consumed more easily by third party build tools. (Or webpack itself, too! E.g. I can't consume CommonJS modules outputted from webpack right now and use |
Turns out... it looks like I already can output CommonJS modules and keep You need to set The only feature which isn't supported in that way is tree shaking, which brings me back to the original feature request. |
@donaldpipowitch thanks for bringing this up, very useful indeed, I would love to contribute too, I am going to try to learn the current code base first... |
Would love to this implemented! |
Have there been any updates to this issue in the past year? Is it being tracked elsewhere? |
Having to learn both webpack and rollup is no fun! Would love to have this implemented in webpack. |
@sokra @TheLarkInn hey guys. if one (me) wanted to start looking at how to resolve this issue would you have any suggestions? any ideas of how much would need to change to support this? i'd be keen to lend some time if you could put me on the right path :-) |
…ck's tree shaking. This is currently *not* supported by Webpack (see webpack/webpack#1979 (comment) and webpack/webpack#2933 for rationale). We workaround this by exposing our babel config to the wild (i.e. js/nagato/babel-options.js). This way we can give full controls for both bundling (i.e. 'tree shaking' in Webpack) and module building (i.e. 'transpiling') to the library users (I hope). We just can't enforce our users to use some huge-sized arbitrary bundle. Users with ES2015+ (or whatever) environment shall `require()` this config file inside their 'webpack.config.js', and use it as a hash object for the `babel-loader`'s `option: ` option. This could be achieved by looking into the `module: ` option in `package.json`; which (I believe) is the default behavior for Webpack when you use the native `import Something from 'other-external-library'` syntax. If this is not desirable, use the fully-transpiled .js file inside our distributed npm package. This could be achieved by referring to the old-school `"main"` value inside the package.json. Disclaimer: By using this method we abandon Webpack-specific aggresive transpilation features for our entire library. This means we can't use Webpack-specific custom `import`s (i.e. importing non-JavaScript files like images (.png, .jpg, etc.) inside our library (.js)). Additional notes: This issue described in the disclaimer section can be workarounded by specifying your library-specific `npm run build` action inside the `prepare` section of package.json.
It seems to me like Webpack is going to need functionality for compiling CommonJS and other formats to ES Modules, am I correct? I've been diving deep into this for the past few days. It seems like the whole world has traditionally been compiling from other formats to CommonJS. There is a popular babel plugin that does this. That problem seems to have been solved quite well by the community. But we need to go the other way, from CommonJS (or other formats) to ES Modules. I'm not sure how much compilation/transpilation Webpack does itself, but that might be outside of its scope. Perhaps a Babel plugin would be the best choice here. Then the functionality could be leveraged by all libraries that need to go from CommonJS -> ES Modules. There is some prior art: Basic Babel plugin for going from CommonJS -> ES Modules (basic, I've already run into a few blocking bugs, no community): https://www.npmjs.com/package/babel-plugin-transform-commonjs-es2015-modules Advanced Rollup plugin for going from CommonJS -> ES Modules (seems very popular, most likely works very well, not very portable outside of Rollup. Might be easy to integrate within Webpack if Webpack has Rollup integration): https://github.com/rollup/rollup-plugin-commonjs As I see it, this functionality should be created independent of Webpack and then incorporated as a dependency, through either a Bable plugin (most ideal), or perhaps a Rollup plugin (already implemented, might need to finagle). Disclaimer, I'm not a heavy Webpack user nor in the Webpack community, these are just my thoughts as I've been trying to tackle the issue of CommonJS -> ES Modules |
I think webpack must wait until CJS / ESM interop has been standarized into node. There are plenty projects that made opinionated choices about it and it could break the existing codebases if things got spec-ed differently. |
Hello, I have a library fully written in Es6, and due to webpack limitations I'm not able to propose my library in es6 module that would enable treeshaking feature on for clients |
@moroine For library, I would recommend using |
Looks like import assertions are being stripped out from external modules. These are needed to import JSON files under nodejs v18.x. import tlds from "tlds" assert { type: "json" }; Becomes: import * as __WEBPACK_EXTERNAL_MODULE_tlds__ from "tlds"; To be honest I didn't troubleshoot this too much. I'm running Webpack v5.73.0 with a pretty in depth configuration that I'm migrating to module output. It's possible babel or someone else is stripping them before it gets to Webpack but I thought I would raise it here. I can work around it by bundling the small handful of JSON files. |
@laverdet sounds like a critical bug, can you open an issue? |
I have followed the documentation, read through much of this issue, tried several of the solutions others have seen work but I still cannot get a library built with Webpack to be tree-shakable. Currently this is all there is to that library configuration (also has
I've set up a repository with a both a Webpack app and a Vite app that consume test libraries built by most of the modern JS build tools (Babel, ESBuild, Vite, Webpack) and the Webpack app correctly treeshakes the exports from all of the libraries except for the one also built with Webpack. We see the same when importing the library built with Webpack into a Vite app. I feel like I may be missing something obvious here but can't seem to get it to work with Webpack. Note: Babel is configured to output ESM.
|
@WalterWeidner Why you need webpack to build ESM library? I think better to keep source code in ESM in nowdays |
In this case the main reason is to limit the API surface area. This way we don't have to worry as much about breaking applications because we simply re-arranged code or because someone was using an implementation detail when they shouldn't be (this library is only used internally). |
There may be many reasons someone needs to build their source code to deliver their ESM library. Off the top of my head could be to deliver to JS code for Vue/React/Angular/etc components, compiled typescript, bundling/externalizing particular dependencies, and reducing potential conflicts with various configs. Compiling typescript with |
Libraries with source code in TypeScript need a build pipeline and simple Achieving any of these use-cases isn't impossible today but would get a lot easier with webpack. |
There is some consensus that consuming a library made of a single "Flat ESM" module (FESM) is more performant for downstream tools than consuming a library made up of tons of small ESM modules. Angular strongly advocates using FESM, shipping all their packages with ESM bundles as a primary format and also advising developers to do the same for their libraries. Of course, the tooling used today requires additional post-processing via Rollup. |
I am curious about why the |
@WalterWeidner Yeah, I see your problem, |
@alexander-akait pulling this repository and then running If that's not what you need I am happy to spin up something else to help get to root of the problem more efficiently. |
@WalterWeidner Yeah, I see your problem, we generate |
How likely is this to be implemented? We might need to adjust our build to use something else if this is unlikely to happen. |
Any updates? I want to use it for libraries, too |
I'm submitting a feature request
It would be nice, if
output.libraryTarget
could support the ES2015 module format.What is the motivation / use case for changing the behavior?
Say I develop a fancy component called
fancy-component
with webpack. I use a very custom config with specific loader settings e.g. for inlining images and stuff like that. My module exportsFancyComponent
andBigFancyComponent
.A friend develops a single page application and uses rollup to do that. He knows nothing about webpack, but wants to use my
FancyComponent
, but notBigFancyComponent
. He installsfancy-component
and importsFancyComponent
.BigFancyComponent
should not be included in the build (because of tree shaking).As far as I know this is currently not possible. My friend would need
fancy-component
in a format using ES2015 modules. But currently these include webpack specific loader logic. I really need to publishfancy-component
without webpack specific logic, but with ES2015 modules.The text was updated successfully, but these errors were encountered: