记一次用vue2开发多页面应用
一.前提
- 项目中有几个页面交互比较多,使用jquery方式实现,交互完成后,需要手动状态修改完成后,比较麻烦。选择使用mvvm模式的vue框架,以数据驱动可以加快开发效率。
- 在此之前,使用vue写过spa应用,且使用官方vue-cli一键完成配置,对webpack不了解,这次尝试自己搭建脚手架。
二.实现
1.webpack配置
webpack的plugin具有很强大的功能,也是webpack相对于其他前端编译grunt,glup具备的优势。可以通过webpack plugin实现热替换,代码压缩混淆,代码分离等工作,帮助我们更好的进行前端开发及优化。
- webpack plugin配置dev与production
在开发流程中,一般需要区分开发环境与生产环境。在开发环境中,进行本地调试开发,在生产环境编译打包文件。
以下,新建webpack.config.dev.js,与webpack.config.js文件分别作为开发环境与生产环境,在dev环境下实现热替换,在prod环境下实现多多页面输出。
使用DefinePlugin区分定义环境
在webpack.config.dev.js的plugin中添加
1 2 3 4 5 6
| plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"dev"' }), ... ]
|
在webpack.config.dev.js的plugin中添加
1 2 3 4 5 6
| plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), ... ]
|
在package.json中添加钩子脚本
1 2 3 4
| "scripts": { "dev": "webpack-dev-server --config webpack.config.dev.js", "build": "webpack --config webpack.config.js" },
|
在vue的spa应用中,单一入口,单一输出,webpack.config.js:
1 2 3 4 5 6 7 8 9
| module.exports = { entry: ['./src/main.js'], output: { publicPath: config.publicPath, path: path.resolve(__dirname + config.publicPath), filename: '[name].js?v=[hash]' }, ... }
|
在多页面应用中,设置多入口,多出口,webpack.config.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| var glob = require('glob'); var path = require('path'); var publicPath = "/dist/"; var entries = getEntry(['./src/views/*.js', './src/views/**/*.js']); module.exports = { entry: entries, output: { path: __dirname + publicPath, publicPath: publicPath, filename: "[name].js", libraryTarget: 'umd' }, ... } function getEntry(globPath) { var entries = {}, basename, tmp, pathname; if (typeof (globPath) != "object") { globPath = [globPath] } globPath.forEach((itemPath) => { glob.sync(itemPath).forEach(function (entry) { basename = path.basename(entry, path.extname(entry)); if (entry.split('/').length > 4) { tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; entries[pathname] = entry; } else { entries[basename] = entry; } }); }); return entries; }
|
添加依赖
1
| npm install webpack-dev-server --save-dev
|
webpack-dev-server实现了一个轻量的node.js express服务器,webpack.config.dev.js配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module.exports = { devtool: "#eval-source-map", devServer: { contentBase: "./src/public/", colors: true, historyApiFallback: true, inline: true, noInfo: true }, plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ] ... }
|
其中contentBase属性为node服务指定的目录,访问本地资源及页面。
2.项目结构
目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| . ├── README.md ├── dist // 输出文件夹 │ ├── vendors.bundle.js // 分离后的通用js │ └── views // 页面输出后的js文件 ├── node_modules // 依赖库 ├── package.json ├── src // 项目主要模块 │ ├── common // 通用js,ajax请求,及全局Vue插件 │ ├── components // vue components │ ├── public // 资源文件及html模板 │ └── views // 主要模块 │ ├── cart // 购物车模块 │ ├── cart.js // vue的初始化 │ └── cart.vue ... ├── stats.json ├── webpack.config.dev.js // 测试环境 └── webpack.config.js // 生产环境
|
src/public
1 2 3 4 5 6
| src/public/ // 作为本地服务器指定的contentBase入口,访问本地资源及页面模板 ├── css ├── display // 本地调试的html模板 ├── font ├── img └── js
|
三.优化
利用webpack plugin对代码压缩,提取分离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| plugins: [ ... new webpack.optimize.CommonsChunkPlugin('vendor', 'vendors.bundle.js'), new webpack.optimize.UglifyJsPlugin({ mangle: { except: ['$super', '$', 'exports', 'require'] }, compress: { warnings: false } }), ]
|