Outputting Library as ES6 module with webpack? - javascript

I'm trying to bundle a library right now and Webpack doesn't seem to have an option for outputting as an ES6 module with output.libraryTarget. I see literally every option but ES6 listed in the documentation.
What's going on here? Am I misunderstanding how webpack works?

It's not implemented yet. See this issue.
You can use Rollup instead, but it expects all modules to be ESM.

With the latest Webpack V5 (as of September 2022), you can do this:
module.exports = {
entry: ["./src/index.ts"],
experiments: {
outputModule: true,
},
output: {
path: `${__dirname}/dist/myOutputFile.mjs`,
library: {
type: "module",
},
},
};
I also set devtool: false and used externals to keep things like React out of the bundle.
See https://github.com/webpack/webpack/issues/2933 (as mentioned in the other response) and https://webpack.js.org/configuration/output/#outputlibrarytype for more details.

Related

Mock library with webpack

I'm attempting to replace a library for testing.
The code I want to change:
import foo from 'foo-lib'; // foo-lib is a library dependency in package.json
I want this to import src/mock-foo.js instead.
This is for end-to-end tests, so I can't use something like Jest mocks.
I have a development-only webpack.config. In that I've tried:
resolve: {
alias: {
'foo-lib': path.resolve(__dirname, 'src/mock-foo.js')
},
extensions: ['.js'], // need this for some other aliases (not shown)
},
I've also tried the older technique in the plugins array:
new webpack.NormalModuleReplacementPlugin(
/foo-lib/,
'mock-foo.js'
),
as well as several variations on these.
I don't get errors, but the original library loads every time.
Is this even possible? If so, what's the correct syntax?
I think I've found one solution based on Replacing/aliasing a file using Webpack .
Testing with the is-number library (just for a simple example), this works:
plugins: [
new webpack.NormalModuleReplacementPlugin(
/is-number/,
require.resolve('./src/mock.js')
),
],
As one of the commenters on the other post mentioned, it's not clear why the resolve.alias approach didn't work.

Tailwind and storybook setup postcss config issue

I have the following postccs.config.js file:
module.exports = {
plugins: [
require("postcss-import"),
require("tailwindcss"),
require("autoprefixer"),
],
}
which allows me to run tailwind and storybook together, however when I try to run my application, I get this error:
Error: A PostCSS Plugin was passed as a function using require(), but it must be provided as a string.
Is there a way to provide a specific storybook postcss config or even a better way for the 2 to work with the same config?
you need to execute the require.
Your config should look like this:
module.exports = {
plugins: [
require('postcss-import')(),
require('tailwindcss')('./tailwind.config.js'), //This refers to your tailwind config
require('autoprefixer'),
],
};
also this was answered before #see: How to configure VueJS + PostCss + Tailwind with Storybook

Use ES6 library's ES5 module without compiling it on my own project with rollup

I need to use an ES6 library (Luxon) and want to compile down the files to ES5, but Rollup adds the files as ES6.
The library has a special /build folder with different output formats.
How can I configure Rollup to make use of that instead of doing nothing with the library?
First of all, you have two options here:
Either compiling the library on your project with Rollup and
#rollup/plugin-babel
Or referencing the /build directory of the package instead of the ES6
version of the package, using an alias with #rollup/plugin-alias
I'll go with the second approach because is the one you asked for:
Install the plugin npm i #rollup/plugin-alias
At rollup.config.js import it import alias from '#rollup/plugin-alias';
Finally, add it to plugins:
const path = require('path');
module.exports = {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [
alias({
entries: [
{ find: 'luxon', replacement: path.resolve(process.cwd(), 'node_modules/luxon/build') },
]
})
]
};

How can I transpile a dependency in node_modules with Nuxt 2?

I have read of issues with transpiling node_modules with Nuxt, but the new Nuxt 2 is said to have solved this with a transpile option in the nuxt.config.js file.
https://nuxtjs.org/api/configuration-build/#transpile
Here is what I have:
export default {
router: {
base: '/',
},
build: {
transpile: [
'choices.js',
'lazysizes',
'swiper',
'vee-validate'
],
extractCSS: true
},
srcDir: 'src/',
performance: {
gzip: true
},
render: {
compressor: {
threshold: 100
}
},
dev: false
}
I removed a few things that are unrelated to make it easier to read.
When I run npm run build (nuxt build) the compiled JS files contain references to es6 and es7 code such as const and let etc when it should be var.
I have isolated this issue to be coming from Swiper. It appears to internally depend on something called Dom7 that seems to be causing the problem.
I am wanting to compile these node_modules dependencies to es5 if possible. I'm not sure my current setup is actually doing anything at all in that regard.
I believe Nuxt uses vue-app for Babel, but I even tried the following to no success:
babel: {
presets: [
'#babel/preset-env'
],
plugins: [
'#babel/plugin-syntax-dynamic-import'
]
}
Not much joy there either. Nothing appears differently in the final build.
I am using Nuxt 2.1.0
Any help appreciated. Thanks!
You also need to transpile Dom7, so the Nuxt config should have:
build: {
transpile: [
'swiper',
'dom7',
],
}
I have the exact same issue.
The vendor option under build is deprecated, so it's simply ignored I believe from what I read here https://medium.com/nuxt/nuxt-2-is-coming-oh-yeah-212c1a9e1a67#a688
I managed to isolate my case to the "swiper" library. If I remove that from my project, all references to let, const or class are gone. I've tried the transpile option too, but it does not seem to have any effect.
Will you try to exclude swiper from your project to see if we can isolate the issue?

'Subject' is not exported by rxjs in rollup.js

I am trying to set up my project to use rollup, as part of an angular2 move to AOT compilation, however, I am getting the following issue.
Error: 'Subject' is not exported by node_modules\rxjs\Subject.js
This is my rollup.js file:
import rollup from 'rollup';
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify'
export default {
entry: 'client/main.js',
dest: 'public/assets/js/build.js',
sourceMap: false,
format: 'iife',
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: 'node_modules/rxjs/**',
include: 'node_modules/angular2-jwt/**',
}),
uglify()
]
}
Why is this happening, I have followed the angular2 cookbook guide?
You'll need to use the namedExports option with rollup-plugin-commonjs: https://github.com/rollup/rollup-plugin-commonjs#custom-named-exports.
Also, you may find it useful to include: 'node_modules/**' rather than individual packages, as otherwise any dependencies of your dependencies will bypass the plugin (in the config above, you have duplicate include properties – perhaps that's just a typo? If you need to pass multiple values, use an array).
commonjs({
include: 'node_modules/**',
namedExports: {
'node_modules/rxjs/Subject.js': [ 'Subject' ]
}
})
I finally figured this out on my system.
The named export solution is wrong since rollup-plugin-commonjs will handle the exports in Subject.js just fine.
The problem for me was the "includes" option in rollup-plugin-commonjs.
There are two issues.
Number one: when specifying the includes in the options as "node_modules/rxjs/**" you have to be sure the full path resolves to where you expect it to.
Example:
I run my build command from "c:/foo/build" but my files are in "c:/my-source" then the include patterns might resolve to "c:/build/node_modules" which means when the commonjs plugin is checking if it should handle "node_modules/rxjs/" it will see that "c:/my-source/node_modules/rxjs/" does not match "c:/build/node_modules/rxjs/**" thus it will not convert the exports to ES6.
The second issue is case sensitivity. The include patterns are case sensitive. This tripped me up too.
Both of these issues can be confirmed by opening the "node_modules\rollup-plugin-commonjs\dist\rollup-plugin-commonjs.cjs.js" file and debugging the "transform" function.
If you modify the code (at the very beginning of the transform function) to be something like this
if (id.includes('rxjs\\Subject.js')) {
debugger;
}
and then run the code in a debugger, you can step through the code until it gets to the filter function. There you will see the filter function is skipping the "rxjs/Subject.js" file.
I almost guarantee this is the problem when the error occurs.
I have found that this can happen in combination with symlinks.

Categories

Resources