前段时间业务那边提出要求,要把项目里面的某个模块独立出来(要求有单独的登录入口)。重新建一个新项目显然是不现实的,这个模块用到了很多项目里面的公用组件,就算是搬运也十分繁琐。而且又需要重新做权限控制(菜单和按钮后端分配的)...
最后就想到了。多入口这个解决方案。可以说是完美的解决了上面所述的问题。
项目不是通过vue-cli构建的,使用的是webpack3.6的版本。vue-cli和webpack4项目配置略有不同。vue-cli在「vue.conifg.js」中配置;webpack4 一般在 「webpack.config.js」配置,主要看你的项目结构。大家自己 Google 和 百度亿下 :
先贴一下项目依赖和有关目录。
- build
- webpack.base.conf.js //webpack公用基础配置
- webpack.dev.conf.js //开发环境配置
- webpack.prod.conf.js //生成环境配置
- config
- index.js
- src
- k1 //新增的入口相关文件
- k1.vue
- index.html
- main.js
- 还有新入口的其他页面功能(与文章多入口配置关系不把,忽略)
- app.vue //原来入口
- main.js //原来的入口文件
- index.html //原来的入口HTML
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"build": "node --max-old-space-size=10240 build/build.js",
"testing": "node build_test/build.js"
},
"dependencies": {
"awe-dnd": "^0.3.1",
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"echarts": "^4.1.0",
"element-ui": "^2.9.1",
"iview": "^2.14.3",
"jquery": "^3.4.1",
"js-cookie": "^2.2.0",
"less": "^3.0.4",
"less-loader": "^4.1.0",
"moment": "^2.22.1",
"v-viewer": "^1.0.1",
"vue": "^2.5.2",
"vue-giant-tree": "^0.1.2",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"wangeditor": "^3.1.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-jest": "^21.0.2",
"babel-loader": "^7.1.1",
"babel-plugin-component": "^1.1.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-import": "^1.7.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"chromedriver": "^2.41.0",
"copy-webpack-plugin": "^4.0.1",
"cross-spawn": "^5.0.1",
"css-loader": "^2.1.1",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"jest": "^24.8.0",
"jest-serializer-vue": "^0.3.0",
"nightwatch": "^1.1.11",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^1.1.2",
"vue-jest": "^1.0.2",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^2.9.7",
"webpack-merge": "^4.1.0"
},
第一步,配置入口以及出口
打开「build\webpack.base.conf.js」文件。找到entry和output entry:K1是添加的入口。仔细看注释。 output,输出(出口),也就配置webpack打包完成后项目存放的路径。多个入口的文件都会打包在一起。
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: ["babel-polyfill", "./src/main.js"], //项目原本的入口相关js
k1: ["babel-polyfill", "./src/k1/main.js"], //新增的独立入口相关js
},
output: {
path: config.build.assetsRoot, //打包之后入口文件硬盘中存放的路径
filename: '[name].js',//打包之后的文件名,[name]对应入口名称 app 和 k1
publicPath: process.env.NODE_ENV === 'production' //「publicPath」对应的是打包之后HTML资源路径的公用部分
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
有个地方值得注意,那就 path 和 publicPath 区别 。path 是打包后文件存放的本地路径。publicPath是写入HTML的资源路径的公用部分。例如:「/k1/static/k1.css」、「/k1/k1.html」。「/k1/」就是publicPath指定的路径
第二步,配置「webpack.dev.conf.js」开发环境
我们先配置好开发环境。打开「webpack.dev.conf.js」里面找到 plugins:[new HtmlWebpackPlugin({})]。在下面添加一个新的html入口。看下方注释
plugins: [
//原本的入口
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
chunks: ['app']
//在原本的入口里面添加chunks。chunks是指定在HTML入口里需要引入的JS。不写这一行默认引入打包的所有入口JS,也就是会引入新入口的JS。会引起冲突。
}),
//新添加的入口
new HtmlWebpackPlugin({
filename: 'k1.html', //打包生成的HTML
template: './src/k1/index.html', //新入口的HTML文件。
inject: true,
chunks: ['k1'] //chunks的值要和entry的属性名对应
}),
]
想了解 HtmlWebpackPlugin 插件的作用可以看一下这篇文章:html-webpack-plugin用法全解
第三步 配置「webpack.prod.conf.js」,生产环境
生产环境的配置,照葫芦画瓢。找到「webpack.prod.conf.js」。添加一个新入口。
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing' ?
'index.html' : config.build.index, //这是生成的文件名,直接写字符串就可以了。
template: 'index.html',
chunks: ['manifest', 'vendor', 'app'], //生产环境和开发环境有些不同,打包时会生成「manifest」和「vendor」所以也要引入。
inject: true,
minify: { //minify的作用主要是一些HTML压缩规则
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency' //指定js的引入规则
}),
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing' ?
'k1.html' : config.build.k1,
template: './src/k1/index.html',
chunks: ['manifest', 'vendor', 'k1'],
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
}),
最后 打包生成最终项目
运行打包命令
npm run build //具体是什么参考一下自己项目的 package.json
这里吐槽一下,自己手上的项目,简直巨无霸!打包都要十几分钟!看我给 node 分配的最大可用内存就知道有多恶心 。 不然分分钟内存溢出
"build": "node --max-old-space-size=10240 build/build.js",
最后,看看打包完成的样子。
可以用 node.js弄个web服务器看一下效果,具体就不展开了。
说得不对地方,请各位大佬指教,多多包涵
文章来自「阿怪的小破站」