Use buid.extend
to config whatever you want in webpack
.
https://nuxtjs.org/faq/extend-webpack#how-to-extend-webpack-config-
@clarkdo
thank you very mush!
Can I ask you further, configuration details should be how to write?
I tried this idea, but failed.
It may be inappropriate for me to do some things, but I do not know how to do it
Maybe sth like:
module.exports = {
build: {
extend(config, { dev, isClient }) {
if (isClient) {
const vendor = config.entry.vendor
// vendor2 is separated vendor file
const vendor2 = [
'vue-router',
'vue-meta'
// and what ever you want
]
// remove from existing vendor
config.entry.vendor = vendor.filter(x => !vendor2.includes(x))
config.entry.vendor2 = vendor2
}
}
}
}
@snoopy83101, pls let me know if @clarkdo 's example is working for you.
I have got strange result, vendor2 dependencies was been added into app chunks
@karmazzin
Do you change the filenames
?
build: {
filenames: {
app: '[name].[chunkhash].js'
}
}
config.entry.vendor = ...
config.entry.vendor2 = ...
Is it okay to just configure config.entry?
There's no need to think about CommonsChunkPlugin?
I'll try your method. Thank you
In Nuxt, a module is extracted into the vendor chunk when it's inside node_modules and used in at-least 1/2 of the total pages.
common chunks are in vendor
by default, if you want to change this rule, you can customize it by changing config.plugins
.
So, I don't have to think about CommonsChunkPlugin.
just
module.exports = {
build: {
extend(config, { dev, isClient }) {
if (isClient) {
const vendor = config.entry.vendor
// vendor2 is separated vendor file
const vendor2 = [
'vue-router',
'vue-meta'
// and what ever you want
]
// remove from existing vendor
config.entry.vendor = vendor.filter(x => !vendor2.includes(x))
config.entry.vendor2 = vendor2
}
}
}
}
All right?
You can also config the filenames
as I mentioned above, or vendor2
name will be like app.....js
Combining build. filenames
E... I think I understand now!
Thank you very much for your help!
@clarkdo I followed above mentioned steps the vendor is still big, and vendor2 is created but so small.
You can try analyse
to find which libs are big and separate them into different vendors.
I'm trying to move vuetify, vee-validate to a different bundle. but as above image it shows only 82 byes. This can't be right.
Could you provide your code ?
A part from my nuxt.config.js
{
...
build: {
analyze: true,
babel: {
plugins: ['transform-decorators-legacy', 'transform-class-properties']
},
filenames: {
app: '[name].[chunkhash].js'
},
extend(config) {
const { vendor } = config.entry;
if (vendor) {
const vendor2 = ['axios', 'vuetify', 'vee-validate'];
config.entry.vendor = vendor.filter(v => !vendor2.includes(v));
config.entry.vendor2 = vendor2;
}
},
vendor: [
'axios',
'vuetify',
'vee-validate',
'nuxt-class-component',
'vue-class-component',
'vue-property-decorator',
'vuex-class'
]
},
// specify additional nuxt plugins
plugins: [
{
src: '~/plugins/vue-notifications',
ssr: false
},
'~/plugins/vee-validate',
'~/plugins/vuetify'
],
...
}
Can you try to remove commonChunksPlugin
or exclude the you vendor2 libs in minChunks
of commonChunksPlugin
.
// sth like
extend(config) {
if (process.client) {
const plugin = config.plugins.find((plugin) => plugin.filenameTemplate === 'vendor.js')
const old = plugin.minChunks
plugin.minChunks = function (module, count) {
return old(module, count) && !(/(axios)|(vuetify)|(vee-validate)/).test(module.context)
}
}
}
@clarkdo doesn't seem to work.
Try :smile:
module.exports = {
build: {
extend(config, { isClient }) {
if (isClient) {
const { vendor } = config.entry
const vendor2 = ['axios', 'vuetify', 'vee-validate']
config.entry.vendor = vendor.filter(v => !vendor2.includes(v))
config.entry.vendor2 = vendor2
const plugin = config.plugins.find((plugin) => ~plugin.chunkNames.indexOf('vendor'))
const old = plugin.minChunks
plugin.minChunks = function (module, count) {
return old(module, count) && !(/(axios)|(vuetify)|(vee-validate)/).test(module.context)
}
}
},
filenames: {
app: '[name].[chunkhash].js'
},
vendor: [
'axios',
'vuetify',
'vee-validate'
]
}
}
That config just made it worse, bundles are now bigger, 😠too bad I don't know much about webpack.
It works for me:
package.json:
{
"name": "nuxt-demo",
"dependencies": {
"axios": "^0.17.1",
"nuxt": "latest",
"vee-validate": "^2.0.3",
"vuetify": "^0.17.6"
},
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start"
}
}
nuxt.config.js
module.exports = {
build: {
extend(config, { isClient }) {
if (isClient) {
const { vendor } = config.entry
const vendor2 = ['axios', 'vuetify', 'vee-validate']
config.entry.vendor = vendor.filter(v => !vendor2.includes(v))
config.entry.vendor2 = vendor2
const plugin = config.plugins.find((plugin) => ~plugin.chunkNames.indexOf('vendor'))
const old = plugin.minChunks
plugin.minChunks = function (module, count) {
return old(module, count) && !(/(axios)|(vuetify)|(vee-validate)/).test(module.context)
}
}
},
filenames: {
app: '[name].[chunkhash].js'
},
vendor: [
'axios',
'vuetify',
'vee-validate'
]
}
}
Before:
-rw-r--r-- 1 clark staff 455189 1 16 16:44 vendor.837fce96c1f7f2ad2abc.js
After:
-rw-r--r-- 1 clark staff 142569 1 16 16:43 vendor.4f9def85ed3690acf031.js
-rw-r--r-- 1 clark staff 312724 1 16 16:43 vendor2.69549d11643f13001613.js
Here's the output, after applying above code
app seems bigger now
That should because libs in app
not extracted into vendor2
, maybe you can add a CommonsChunkPlugin
for extracting common chunks.
You can take a look at https://github.com/webpack/webpack/issues/4445#issuecomment-285187130
@BruceHem Would you please also share nuxt build --analyze
results too? Also using nuxt-edge@latest
dependency instead of nuxt
for latest changes :)
How about:
const webpack = require('webpack')
module.exports = {
build: {
extend(config, { isClient }) {
if (isClient) {
config.entry.vendor = config.entry.vendor.filter(v => !['axios', 'vuetify', 'vee-validate'].includes(v))
config.plugins.unshift(
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
children: true,
async: 'vendor2',
minChunks(module, count) {
return /(axios)|(vuetify)|(vee-validate)/.test(module.context)
}
})
)
}
},
vendor: [
'axios',
'vuetify',
'vee-validate'
]
}
}
@clarkdo thanks for the examples provided, I'm having the same issue.
My vendor chunk is about 800KB. I tried the solutions suggested, in the first case vendor2 is a few bytes, in the second case app and vendor are bigger, as it happened to @BruceHem.
@pi0 If I run analyze the interface doesn't show the vendor2 chunk, all the node_modules I associated to it seems to be still under the vendor chunk.
Update
@pi0 I managed to get the vendor2 chunk in the -analyze view, by implementing the example of @clarkdo, however I see that the node modules of vendor2 are duplicated in app.0302932039032.js chunk.
extend (config, { isClient }) {
if (isClient) {
const { vendor } = config.entry
const vendor2 = ['adyen-cse-js', 'vuelidate', 'elliptic', 'bn.js']
config.entry.vendor = vendor.filter(v => !vendor2.includes(v))
config.entry.vendor2 = vendor2
const plugin = config.plugins.find((plugin) => ~plugin.chunkNames.indexOf('vendor'))
const old = plugin.minChunks
plugin.minChunks = function (module, count) {
return old(module, count) && !(/(adyen-cse-js)|(vuelidate)|(elliptic)|(bn\.js)/).test(module.context)
}
}
},
filenames: {
app: '[name].[chunkhash].js'
},
vendor: [
'vuelidate',
'adyen-cse-js'
]
@pi0 image below for reference.
Trello card created (https://trello.com/c/5bL1gNbg/78-vendor-optimizations)
Thanks to the Nuxt.js Team, you are doing an awesome work!
@pi0 nice 🖖
This definitely needs work. I have less than 10 pages and my vendor.js
is 200kb.
app.js
is around 50 kb.
I don't feel like I have written so much though.
Good news: With Webpack 4 vendor will be automatically split into smaller chunks for both perf and long-term caching. We are going to work on it.
I'm working on an PR about that (webpack 3)
@pi0 @clarkdo
my proposal: https://github.com/nuxt/nuxt.js/pull/2687
Updates on this? Vendor bundle is still huge.
@ALL any update? My vendor is 1.75MB I want to split it :( I don't know how though..
This is part of my nuxt.config.js
build: {
babel: {
plugins: [
["transform-imports", {
"vuetify": {
"transform": "vuetify/es5/components/${member}",
"preventFullImport": true
}
}]
]
},
// cssSourceMap: false, // add this into the nuxt.config
extend (config) {
config.devtool = false
},
vendor: [
// '~/plugins/vuetify.js',
// '~/plugins/vee-validate.js',
'firebase'
],
optimization: {
splitChunks: {
chunks: 'all',
automaticNameDelimiter: '.',
name: true,
cacheGroups: {},
minSize: 100000,
maxSize: 100000
}
},
maxChunkSize: 100000,
extractCSS: true,
/*
** Run ESLint on save
*/
extend (config, ctx) {
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
if (ctx.isServer) {
config.externals = [
nodeExternals({
whitelist: [/^vuetify/]
})
]
}
}
}
@besnikh vendor
has been deprecated due to webpack4
has used SplitChunksPlugin
to automatically generate common chunks.
The reason may be because your config doesn't meet default conditions of the strategy, try to change maxAsyncRequests
or maxInitialRequests
or provide a reproducible repo, but webpack
default configurations should be the best practice and recommendation 😄 .
I just updated to nuxt-edge
(and webpack 4
), but I still get big bundle sizes:
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
5ee7cf173fbbbd29401e.js (1.19 MiB)
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (1000 KiB). This can impact web performance.
Entrypoints:
app (1.4 MiB)
1d2359df0b3a4c1ac2bc.js
5ee7cf173fbbbd29401e.js
a51c2c1bcf724420734d.js
Is there anything that needs to be changed / configured?
My nuxt.config.js
does not have changed any build
settings.
there's no vendor any more?
where to config vendors.app ?
yarn build
yarn run v1.9.4
$ NODE_ENV=production nuxt build
[15:14:22] Building project
[15:14:22] Builder initialized
[15:14:22] Nuxt files generated
undefined
undefined
[15:14:23] Compiling client
[15:14:35] Compiled client in 13s
Hash: 9c140484c85ee4351c71
Version: webpack 4.17.1
Time: 12716ms
Built at: 2018-08-30 15:14:35
Asset Size Chunks Chunk Names
a8fb3b858aa32b7162be.js 215 KiB 0 [emitted] app
0ab00c424448a26b6ae7.js 556 bytes 1 [emitted] pages/index
1f1e22a52a1f27462980.js 133 KiB 2 [emitted] commons.app
94284cfffbf18ce8aa7e.js 378 KiB 3 [emitted] [big] vendors.app
LICENSES 76.1 KiB [emitted]
+ 3 hidden assets
Entrypoint app = 1f1e22a52a1f27462980.js 94284cfffbf18ce8aa7e.js a8fb3b858aa32b7162be.js
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
94284cfffbf18ce8aa7e.js (378 KiB)
[15:14:35] Compiling server
Webpack Bundle Analyzer saved report to /Users/willin/Desktop/nuxt-edge-split-vendors/.nuxt/stats/client.html
[15:14:43] Compiled server in 8s
Hash: d246aef4a1691711c8dc
Version: webpack 4.17.1
Time: 7700ms
Built at: 2018-08-30 15:14:43
Asset Size Chunks Chunk Names
server-bundle.json 605 KiB [emitted]
Entrypoint app = server-bundle.js server-bundle.js.map
Webpack Bundle Analyzer saved stats file to /Users/willin/Desktop/nuxt-edge-split-vendors/.nuxt/stats/client.json
✨ Done in 23.45s.
You should reopen this issues, since Nuxt 2 have no vendor
and I have the same warning, that I can't solve. How to split big package into separate file?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
config.entry is undefined
FYI
Comment of big vendors.app.js
question: https://github.com/nuxt/nuxt.js/issues/5545#issuecomment-484577422
for me it was just enough to reduce chunk sizes not more than 50 Kib, so I hack it like so:
extend (config, ctx) {
if (ctx && ctx.isClient) {
config.optimization.splitChunks.maxSize = 51200
}
}
this is my output logs on npm run generate
command:
Hash: 55f650db95c0aedbeaab
Version: webpack 4.41.4
Time: 19182ms
Built at: 12/19/2019 8:28:56 PM
Asset Size Chunks Chunk Names
../server/client.manifest.json 15 KiB [emitted]
0cde51ddddffebfe69e4.js 26.1 KiB 5 [emitted] [immutable] commons.app.5bec50a0
156f5330576e65671f1d.js 22.9 KiB 1 [emitted] [immutable] app.f69643ec
160cec1d41e28590bf6e.js 226 KiB 18 [emitted] [immutable] vendors.app.a2a2526c
238517e577d836f5c0d0.js 64.4 KiB 8 [emitted] [immutable] commons.app.aaac3122
376425dd0a427b29f483.js 15.8 KiB 17 [emitted] [immutable] vendors.app.78934547
3a8b86e990c2c8a1a949.js 25.8 KiB 19 [emitted] [immutable] vendors.app.c1e9ae2e
423a295fbea8fa5666ec.js 13.1 KiB 9 [emitted] [immutable] commons.app.d939e436
4f7286dd41f72a49b6e5.js 14.3 KiB 3 [emitted] [immutable] commons.app.253ae210
5165ef6d7ba2a603815b.js 14.7 KiB 2 [emitted] [immutable] commons.app.0605657e
5cf237a5a2cd21c7b478.js 28.6 KiB 16 [emitted] [immutable] vendors.app.74e9f0c9
603f0a39e70c50006343.js 16.4 KiB 14 [emitted] [immutable] vendors.app.1655f327
6d3100c4946db9800ced.js 9.48 KiB 20 [emitted] [immutable] vendors.app.c964cbd5
7559d7be9c8cb40cba33.js 15.5 KiB 21 [emitted] [immutable] vendors.app.ce053847
LICENSES 571 bytes [emitted]
a3e7a86e0cfea400b019.js 15.1 KiB 22 [emitted] [immutable] vendors.app.d939e436
a4df04ec317d52b2f100.js 2.18 KiB 11 [emitted] [immutable] pages/index.31ecd969
a57aa1fcf1c9dfeb2548.js 20.7 KiB 0 [emitted] [immutable] app.24120820
c3fa29ab46b642fc22be.js 38.2 KiB 15 [emitted] [immutable] vendors.app.24f645c1
d4d4e98c0163682fe1cc.js 10.3 KiB 10 [emitted] [immutable] commons.app.fdc6512a
d736b41f2151ef8b55c2.js 8.89 KiB 7 [emitted] [immutable] commons.app.678f84af
d95f06092007a91d3ea0.js 15.8 KiB 4 [emitted] [immutable] commons.app.2a42e354
e46d9b1a3cf3197879a8.js 28.5 KiB 13 [emitted] [immutable] vendors.app.11c2601a
feb4891a9784216e4451.js 13.8 KiB 6 [emitted] [immutable] commons.app.5c956a7a
runtime.8300a73d8568ed857bdb.js 2.31 KiB 12 [emitted] [immutable] runtime
+ 2 hidden assets
Entrypoint app = runtime.8300a73d8568ed857bdb.js 4f7286dd41f72a49b6e5.js d95f06092007a91d3ea0.js
423a295fbea8fa5666ec.js feb4891a9784216e4451.js d736b41f2151ef8b55c2.js d4d4e98c0163682fe1cc.js
5165ef6d7ba2a603815b.js 0cde51ddddffebfe69e4.js 238517e577d836f5c0d0.js a3e7a86e0cfea400b019.js
376425dd0a427b29f483.js 603f0a39e70c50006343.js 5cf237a5a2cd21c7b478.js 7559d7be9c8cb40cba33.js
3a8b86e990c2c8a1a949.js 6d3100c4946db9800ced.js e46d9b1a3cf3197879a8.js c3fa29ab46b642fc22be.js
160cec1d41e28590bf6e.js a57aa1fcf1c9dfeb2548.js 156f5330576e65671f1d.js
Hash: e8905e5151dbbb6711f0
Version: webpack 4.41.4
Time: 12291ms
Built at: 12/19/2019 8:29:08 PM
Asset Size Chunks Chunk Names
8495f3a3db1592ed83bc.js 1.63 KiB 1 [emitted] [immutable] pages/index
server.js 410 KiB 0 [emitted] app
server.manifest.json 145 bytes [emitted]
Entrypoint app = server.js
ℹ Generating pages 20:29:09
✔ Generated /
Regards,
Maksim
@daggerok How about the entry point too big? Your solution worked though. But I dont know what is entry point?
@mandaputtra
entry point also will be reduce by chunks size. just try configure like i did and see what will happen
@daggerok
Okay I'm understand, the entry point is where you firstload the app. Thanks your solution worked, I just need to found what the best config.optimization.splitChunks.maxSize
for me.
@daggerok solution is working awesome
you can change maxSize property in optimization.splitChunks,maxSize too.
export default {
build: {
extractCSS: true,
optimization :{
splitChunks: {
chunks: 'all',
automaticNameDelimiter: '.',
name: 'test',
maxSize : 256000
}
}
},
}
Most helpful comment
for me it was just enough to reduce chunk sizes not more than 50 Kib, so I hack it like so:
this is my output logs on
npm run generate
command:Regards,
Maksim