Compile error
ERROR in ./resources/assets/admin/app.js
Module build failed: Error: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.
plugins: [
['some-plugin', {}],
['some-plugin', {}, 'some unique name'],
]
I found that webpack-merge cannot remove duplicate configurations, How can I solve this?
Because I need to use "useBuiltIns": "usage" to handle compatibility, Operating under laravel
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": [
"> 2%"
]
},
"useBuiltIns": "usage",
"forceAllTransforms": true
}
]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
npm run devThis was mentioned here: https://github.com/JeffreyWay/laravel-mix/pull/1807#issuecomment-444438168
The answer is that Laravel Mix uses @babel/preset-env behind the scenes already and you don't have to do it on your own - so just remove that preset from you .babelrc file.
After further thinking, I think that there should be a way to somehow modify default Babel configuration there. Plus, useBuiltIns: 'usage' should be used as default.
Any thoughts @JeffreyWay?
Okay, this is fixed. We now use a smarter merging strategy, so that your nested Babel config overrides Mix's. This will be included as part of Mix v4.
https://github.com/JeffreyWay/laravel-mix/commit/2c90afc0005d7863c52d7581f9170ef06b2c4349
@JeffreyWay The result of the deepmerge merge is the same as webpack-merge, Try https://github.com/neutrinojs/babel-merge ? or useBuiltIns: 'usage' should be used as default.
I tested it and it works. Are you sure you're using the master branch to test it out?
@JeffreyWay My package.json configuration is "laravel-mix": "github:JeffreyWay/laravel-mix", This configuration is the master branch
I wrote a unit test case
test.serial(
'mix.babelConfig() can be used to merge custom Babel unique options.',
t => {
mix.babelConfig({
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage'
}
]
]
});
t.true(Config.babel().presets.filter(i => i[0] === '@babel/preset-env').length === 1);
}
);
my test result
/Users/stevie/project/my/laravel-mix/test/features/babel.js:27
26: });
27: t.true(Config.babel().presets.filter(i => i[0] === '@babel/preset-env').length === 1);
28: }
Value is not `true`:
false
Config.babel().presets.filter(i => i[0] === '@babel/preset-env').length === 1
=> false
Config.babel().presets.filter(i => i[0] === '@babel/preset-env').length
=> 2
Config.babel().presets.filter(i => i[0] === '@babel/preset-env')
=> [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
},
],
[
'@babel/preset-env',
{
forceAllTransforms: true,
modules: false,
targets: Object { … },
},
],
]
my code link https://github.com/stevieyu/laravel-mix/commit/0396ebd4d647b5cbd77d6f7bee09ecf9941a9fb7
Hmm - you're right. I guess my test was missing a check for duplicates. I think I've fixed this now.
https://github.com/JeffreyWay/laravel-mix/commit/83f5052eb32c498a90edace47402d66eaf80f4b7
@JeffreyWay Thank you, the test is successful, you can publish a version 3.x of?
@JeffreyWay
Right now @babel/preset-env is quite useless: https://babeljs.io/docs/en/babel-preset-env#usebuiltins-false
When you run Mix with preset-env debug mode enabled, you can see:
>Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
So I suppose preset-env should be removed from Mix entirely to avoid confusion.
A 3.x update with this fix would be useful, please?
I can't use 4.x due to dynamic imports.
Otherwise, I'll have to downgrade back to 2.x with Babel 6 instead of 7.
What's wrong with dynamic imports on 4.x?
@adriandmitroca Laravel Mix 4.x uses Webpack 4.x which has compile issues with dynamic imports. We're supposed to hold off until Webpack 5 is out.
See: https://laravel-mix.com/docs/4.0/upgrade#notes
If your project heavily uses JavaScript dynamic imports, you may need to hold off until the release of webpack 5 early next year. There are known compile issues related to this that we cannot fix until then. Once webpack 5 is out, Mix will be updated shortly after. If you're unfamiliar with dynamic imports, then this very likely won't affect your project.
I am using dynamic imports on daily basis with Mix 4.x in several projects and haven't faced any issues to be honest.
@adriandmitroca How many dynamic imports do you have? I'm curious because I've run into compiler issues after upgrading to Mix 4.x and could only conclude the issue is related to the above comment. The project in question has likely over a hundred dynamic imports
@james-brndwgn
20-50 dynamic chunks
@adriandmitroca Thanks. I think that may be where the problem is. I guess after a certain threshold the compiler stalls. Hopefully Webpack 5 comes out soon as I'd love to upgrade the project.
@adriandmitroca How did you solve the issue with chunks paths I have following issue with webpack 4 and didn't find any way to solve this https://github.com/JeffreyWay/laravel-mix/issues/1999
I've discovered that dynamic imports fail when you use it together with Vue components that contain styles.
The workaround for this is one of following:
1) dropping dynamic imports
2) dropping styles within Vue single file components
3) downgrade to Mix v3
@vedmant
@adriandmitroca I don't have styles in my Vue components, but it still fails, specifically it generates wrong paths in manifest file as well as places chunks in the wrong folder.
@vedmant I went down this path again recently to see if I could hone in on the build stalling issue. During that process I discovered that chunked files and non-chunked were being placed in different directories. It seems the configuration with file naming has some bugs. If you use chunkFilename then any mix.js() entries will also be affected.
For example:
mix.js('app.js', 'public/js')
mix.webpackConfig({
output: {
chunkFilename: 'js/[name].chunk.js'
}
});
would place the chunks in /js/ however the non chunked files would end up in /js/js/. The manifest was also then using incorrect paths because of this. Unfortunately I'd already burned enough time trying to figure out the issue so I couldn't find the root cause of it.
@james-brndwgn Yes, I had the same issue with v4, and didn't find any solutions, so I downgraded to v2, as v3 has another issue with env presets that's not fixed. It looks like nothing will be done until webpack 5 release.
@JeffreyWay any way we can backport this to mix v3.x as well?
So I rewrote all my scripts to get rid of dynamic imports.
I also stopped depending on Laravel Mix. I upgraded from Babel 6 to Babel 7 and wrote my own vanilla webpack 4 config with just the loaders I need.
Laravel Mix is great to get started with, but when there's too much abstraction on top, it's probably easier to just go back to the basics.
@yansern Been thinking about doing this myself. How did you go about hash versioning with a manifest file? Did you have to write a custom "mix" like function to use with your blades?
@james-brndwgn Use the webpack manifest plugin and [contenthash] in the output filename. :)
@james-brndwgn It seems using a similar approach to what you have above works out of the box.
}).webpackConfig({
output: {
publicPath: '/',
chunkFilename: 'js/[name].js?id=[chunkhash]'
}
)
By the way, I decided to split my webpack files into multiple ones to avoid the duplicate plugin issue. I now have a dedicated webpack.mix file for the frontend and the backend.
@yansern
Use the webpack manifest plugin and [contenthash] in the output filename. :)
Thank you, can you give me more information on how you did this? e.g. a code sample
Most helpful comment
Hmm - you're right. I guess my test was missing a check for duplicates. I think I've fixed this now.
https://github.com/JeffreyWay/laravel-mix/commit/83f5052eb32c498a90edace47402d66eaf80f4b7