- 仅调用test(),为何xlsx会被bundle?
- 仅调用test(), 为何xlsx出现在vendors中?
环境:vue2、webpack4
实验:@/utils/index中1个xlsx函数,1个test函数。组件仅用test(),为何xlsx会被bundle?为何xlsx出现在vendors中?
代码:@/utils/index.js
import * as XLSX from 'xlsx'
export const excelToJson = () => {
console.warn('@/utils/index.excelToJson is used')
return XLSX + 'excelToJson';
}
export const test = () => {
console.warn('@/utils/index.test is used')
return 'test'
}
export const test2 = () => {
console.warn('@/utils/index.test2 is used')
return 'test2'
}显然:有chunk: inital中的vue, vue-router, core-js,没有xlsx
代码:Home.vue
import { test } from '../utils/index.js'
export default {
name: 'Home',
created () {
console.log(test())
},
}😳 显然:有了xlsx。但是并没有使用到excelToJson(),
🤔 猜测:因为webpack4使用了scope-hosing(👺👺👺),@/utils/index中涉及的code都会被编译进去
代码:About.vue
import { test } from '../utils/index.js'
export default {
name: 'About',
created () {
console.log(test())
},
}😳 显然:有了xlsx。但是并没有使用到excelToJson(),
🤔 猜测:因为webpack4使用了scope-hosing(👺👺👺),@/utils/index中涉及的code都会被编译进去
webpack配置代码
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\\/]node_modules[\\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
},实例:Try000 Try010
chunk: inital阶段涉及的node_modules的文件库会被放到chunk-vendors.js中。 在第2点中做解释。
实例:Try010
Home.vue发生在chunk: inital阶段,因为router中Home.vue直接引用的,而About.vue是动态引用的,所以xlsxbundle到chunk-vendors
代码:router/index
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]将home.vue 和 about.vue 都使用test()函数,xlsx应该会 会pack到chunk-vendors.js中(实验成功,因为home.vue 是直接引用)。
ps:common配置中,对chunks配置all async initial 无效
共享
代码:router/index
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
// component: Home,
component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue') // 实验minChunks: 2
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router代码:home.vue, about.vue 均使用 test()
📣 📣 Note: 如果将Home.vue改成动态引入,就不会发生上面的截图了。
实例:Try020
证明上面截图中的xlsx + buffer:
虽然excelToJson()被标记为unused + harmony export,将被shaking掉,但是1146 xlsx不会干掉。
被证明了猜测?? 因为webpack4使用了scope-hosing,@/utils/index中的cmd 代码会all export used全部打进去了??
- 起初的思考是:使用
esm下的import应该只是引用关系,不会发生cmd 下的require拷贝代码现象,所以xlsx不被bundle才对。 - 其实错了,上面提到的是两个不同的机制,是在js 环境下的代码运行机制;并不是webapck的打包机制。😭😭
😁 😁看bundle文件的引用路径就知道了,引入的路径是真个文件,不是单个test()方法 😭 😭
- bundle过程中,就是将对应的code进行打包。不管你是esm 还是 cmd,所用代码都会bundle。
- 只不过 esm的相关代码,会通过静态结构分析进行标注
unused harmony, 被 shaking - webpack4 在针对cmd时,直接给了一个命名空间,并标识 all export,而这部分代码是不会被 shaking的
通过Try010、Try020,可知,关键点chunks: inital
如果你在入口文件中有直接引入,则被bundle到vendors中(Try010)
如果你没在入口文件中没有直接引入,则不会(Try020)
关于lodash的最佳推荐,有了新感悟,参考实验项目:webapck4-try-bundle-esm-cmd
其实vue-try-chunk-inital-xlsx 与 webapck4-try-bundle-esm-cmd 的 webpack config差别不是太大,起初的目的是看vuecli默认的webpack打包效果,而后又模拟了一份配置而已。
🌹 🌺 🌻 🌷 🌱 🌲 🌳 🌴 🌵 🌾 🌿 🍀 🍁 🍂 🍃








