本文主要介绍如何在此基础上来改造为多入口。php
多入口指的是 webpack 配置项 entry 配置为包含多个 key 的数组或者对象,即 MPA(multiple entry points),那么什么状况下会配置多入口?通常用 vue 大部分是作 SPA(one entry point),由于 SPA 能更好的配合 vue-router,那么我我的想到了几个可能的场景,下面将结合设想的场景来讲明如何配置。css
Github地址:https://github.com/qinshenxue/vue2-vue-router2-webpack2html
前台页面和后台管理页面都放在一块儿,目录结构以下(在《从零搭建 vue2 vue-router2 webpack3 工程》的工程目录上改造)。前端
mpa1 |---- build |---- src |---- admin // 后台管理 | |---- views | |---- app.vue | |---- main.js | |---- router.js | |---- web // 移动端 |---- views |---- app.vue |---- main.js |---- router.js
固然也能够认为就是两个独立的模块,各自都有一套前端路由,只是模块之间存在不少公共的第三方库。对于这种结构,咱们但愿最终生产构建可以达到如下目标:vue
上述目标用目录表示以下。node
mpa1 |---- src |---- dist |---- web | |---- index.html | |---- admin | |---- index.html | |---- assets |---- js | |---- manifest.js | |---- vendor.js | |---- web-vendor.js | |---- admin-vendor.js | |---- web.js | |---- admin.js | |---- css |---- web-vendor.css |---- admin-vendor.css |---- web.css |---- admin.css
下面开始一步一步调整配置,最终达成上面全部的目标。webpack
首先固然要在 webpack.base.config.js 添加 web 和 admin 的入口。ios
entry: { web: path.resolve(__dirname, '../src/web/main.js'), admin: path.resolve(__dirname, '../src/admin/main.js') }
不管是提取各个入口的公共模块(例如 vue、vue-router ),仍是提取 web 和 admin 各自引入的第三方库,都只须要用 webpack 自带的插件 webpack.optimize.CommonsChunkPlugin。git
先将 web 和 admin 各自引入的第三方模块提取到 vendor。github
[ new webpack.optimize.CommonsChunkPlugin({ name: 'web-vendor', chunks: ['web'], minChunks: function (module) { return module.context && module.context.indexOf("node_modules") !== -1; } }), new webpack.optimize.CommonsChunkPlugin({ name: 'admin-vendor', chunks: ['admin'], minChunks: function (module) { return module.context && module.context.indexOf("node_modules") !== -1; } }) ]
接着将 web-vendor 和 admin-vendor 中公共的模块提取为 vendor。
[ // ... new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', chunks: ['admin-vendor', 'web-vendor'] }) ]
最后提取 vendor 中的 webpack 模块加载部分的代码。
[ // ... new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }) ]
CSS 提取采用 extract-text-webpack-plugin 插件。可是配置不须要那么复杂。
[ new ExtractTextPlugin({ allChunks: true, filename: "css/[name].css?[contenthash:8]" }) ]
那么如何提取 web 和 admin 引入的第三方库的 CSS 呢?其实在上面配置 web-vendor 和 admin-vendor 的时候就完成了。
生成页面采用 html-webpack-plugin。不一样于单入口,须要手动配置 chunks,chunks 配置每一个入口依赖的“模块”(chunk)。
[ new HtmlWebpackPlugin({ filename: path.resolve(__dirname, `../dist/web/index.html`), template: 'index.tpl.html', chunks: ['manifest', 'vendor', 'web-vendor', 'web'], inject: true }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, `../dist/admin/index.html`), template: 'index.tpl.html', chunks: ['manifest', 'vendor', 'admin-vendor', 'admin'], inject: true }) ]
以上就是全部的配置,知足了全部咱们但愿达到的构建目标。能够 git clone 文章开头给出的 github 地址尝试一下,注意要切换到分支 mpa1。
不用端路由,采用后端路由,页面多是 php、jsp、aspx,实际开发中这种状况也比较多。这种有点像使用了经常使用模块加载库(seajs,requirejs)同样,每一个页面都须要引入本身的依赖项。目录结构以下。
mpa2 |---- build |---- src |---- css |---- images |---- pages |---- moduleA | |---- index.vue | |---- index.js | |---- moduleB | |---- index.vue | |---- index.js | |---- moduleC |---- index.vue |---- index.js
对于这种结构,构建目标和场景一相似,具体以下。
entry: { moduleA: resolve('../src/pages/moduleA/index.js'), moduleB: resolve('../src/pages/moduleB/index.js'), moduleC: resolve('../src/pages/moduleC/index.js') }
当你模块特别多的时候,这样写确定很差维护,能够本身写一个函数来生成。
[ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', chunks: ['moduleA', 'moduleB', 'moduleC'], minChunks: function (module) { return module.context && module.context.indexOf("node_modules") !== -1; } }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }) ]
css 提取和场景一相同,就再也不说明了。
这里我把生成页面的改成函数生成。
var isProd = process.env.NODE_ENV === "production"; exports.genHtmlPlugins = function () { var baseWebpackConfig = require('./webpack.base.config'); var path = require('path') var plugins = []; Object.keys(baseWebpackConfig.entry).forEach(function (name) { plugins.push( new HtmlWebpackPlugin({ filename: isProd ? path.resolve(__dirname, `../dist/${name}/index.html`) : `${name}/index.html`, template: 'index.tpl.html', chunks: isProd ? ['manifest','vendor', name] : [name], inject: true })) }) return plugins }
上面的函数区分了当前环境,开发环境下,filename 配置为入口名/index.html
,对应访问地址为http://localhost:8090/moduleA/
,开发模式下也不须要用到 CommonsChunkPlugin,所以 chunks 只有一个,而在生产构建时,须要指定 chunks。
最终构建后的目录结构以下。
mpa2 |---- src |---- dist |---- moduleA | |---- index.html | |---- moduleB | |---- index.html | |---- moduleC | |---- index.html | |---- assets |---- js | |---- manifest.js | |---- vendor.js | |---- moduleA.js | |---- moduleB.js | |---- moduleC.js | |---- css |---- vendor.css |---- moduleA.css |---- moduleB.css |---- moduleC.css
上述两个场景的配置大同小异,实际上就是经过 CommonsChunkPlugin 和 HtmlWebpackPlugin 这两个插件来完成你想要的目标。