@(HTML/JS)javascript
通常来讲,使用vue作成单页应用比较好,但特殊状况下,须要使用多页面也有另外的好处。例如手Q的多webview架构,新开页面有利于ios右划返回,也避免了返回时页面的刷新。
因此,这里咱们探讨一下如何配置实现多页面的项目框架。这里是开篇,先以最简单的纯前端多页面为例入手,最终目标是完成Node.js多页面直出+先后端同构的架构。css
本文源代码:https://github.com/kenkozheng/HTML5_research/tree/master/Vue-Multipages-Webpack3html
本文目录,也是实现纯前端多页面的步骤前端
vue-cli
搭建基本的框架vue-cli是官方提供的脚手架工具,快速创建原型项目。vue
npm i -g vue-cli
vue init <template-name> <project-name>
这里我选择最简单的template:webpack-simple。先建立项目目录,而后在目录内运行vue init webpack-simple
,一路yes下去java
而后,咱们会获得这样的目录结构:
!node
vue-cli把project.json、webpack配置还有npm脚本都准备好了,很赞。咱们只须要两步便可运行项目webpack
# install dependencies npm install # serve with hot reload at localhost:8080 npm run dev # build for production with minification npm run build
运行npm run dev就能够启动默认的在8080端口监听的服务器,带有webpack热更新全家桶,很是方便。
不过,咱们须要看懂里边全部源码,才能进行下一步的操做。ios
细节的配置不少,原型项目使用了env这个插件,并设置module相关的语法不转义(留给webpack处理)git
["env", { "modules": false }]
entry: './src/main.js', output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js' }
entry能够为数组或对象或单个字符串,指定须要打包的文件;
output指定打包后输出的信息。这里最好参考官方文档,实在不行就看源码,各类网上文章可能都会说错,包括我这一篇。官方文档:https://doc.webpack-china.org/concepts/output/
关键点是,filename能够用[name].[hash:8]等关键字的方式实现根据entry输入而动态变化的文件名,后续会用到。
path和publicPath须要重点区分一下。
module: { rules: [ { test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], } ... { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } ] }
再看看module,这里从2.x开始就改了格式,一目了然,就是各类文件应该使用什么loader去加载处理。
主要须要关心最后这个file-loader,name要跟以前publicPath配合好,除了写文件名还能够写目录,webpack会自动建立目录存放文件。
resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] }, devServer: { historyApiFallback: true, noInfo: true, overlay: true }, performance: { hints: false }, devtool: '#eval-source-map'
resolve的alias目的是作一个别名映射,当代码中出现vue$时,能够动态替换为对应的字符串。
devServer控制webpack自带的热更新服务器的行为,例如修改一下端口。使用npm脚本运行:webpack-dev-server --open --hot
。须要注意的是,devserver使用memory-fs,并不直接写文件系统。配合WriteFilePlugin能够强制写入。若是不使用devserver调试,例如fiddler替换,就须要强制写入文件系统了。
performance能够先略过
devtool是控制生成的源代码source-map功能,按照默认便可,具体的使用原理简单说,就是浏览器支持的混淆后代码映射到源文件的映射表。
process.env.NODE_ENV === 'production' new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false } })
最后判断了环境变量,若是是生产发布,再加上uglify插件。这里的参数设置能够参考uglify插件自己。
环境变量的设置,使用的是cross-env工具,在npm脚本中运行设置的cross-env NODE_ENV=production
这两个就是很基本的vue功能了。须要关注的是,如今只有一个index.html,并且index.html的功能比较单一纯粹引入js。作多页面时,html如何复用,是须要考虑的问题。
了解了原型项目的功能,接下来须要作的事情包括:
如图所示
var pages = ['page1', 'page2']; //能够根据项目状况,自动分析目录文件生成 var entry = {}; pages.forEach(function (pageName) { entry[pageName] = `./src/pages/${pageName}/main.js`; }); ////////////// module.exports = { entry: entry, output: { path: path.resolve(__dirname, `./dist/`), publicPath: process.env.NODE_ENV === 'production' ? '/' : '/dist/', //发布后在线访问的url。dev模式下,使用的是express在当前项目根目录启动 filename: `[name].js` //'[name].[chunkhash].js', '[name].[hash:8].js' } ...
主要是filename使用了动态的配置方式,会根据entry的key映射。
由于index.html内容简单,咱们不必每一个页面都复制一份。而别人早就想到这个了,因此有了html-webpack-plugin
。
老规矩,npm install起来
而后,修改webpack配置
pages.forEach(function (pageName) { module.exports.plugins.push( new HtmlWebpackPlugin({ title: pageName, filename: `${pageName}.html`, template: `./src/pages/tpl.html`, chunks: [pageName], inlineSource: '.(js|css)$' // embed all javascript and css inline。结合HtmlWebpackInlineSourcePlugin才有效果 }) ); });
根据pages数组的配置,自动建多个HtmlWebpackPlugin实例插到配置中。
顾名思义,配置起了比较简单,详情参考官网:https://github.com/jantimon/html-webpack-plugin
inlineSource是特殊的字段,后续再说。
至此,就能够把项目跑起来了,dev模式下,webpack每次自动打包都会生成page1和page2。
全局共用css的打包
在页面main.js中,直接import便可,最终会转换为注入到html的js代码。
import '../../css/base.css'
图片打包文件名管理
{ test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' //自动hash命名图片等资源,并修改路径。路径须要根据项目实际状况肯定。语法参考:https://doc.webpack-china.org/loaders/file-loader/ } }
每每图片发布后都是长缓存,那么在文件名中加入hash作版本区分是个好方式。另外,使用独立的目录,更方便cdn设置缓存时间。
html、js、css打包到一块儿,减小请求
多页面决定了每一个页面不会太大,对于目前的移动互联网来讲,打包在一块儿的html会比多个js请求更快。
这咱们须要用到HtmlWebpackInlineSourcePlugin
,也就是刚才提到的inlineSource字段。
module.exports.plugins.push( new HtmlWebpackInlineSourcePlugin() //内联css、js。配合HtmlWebpackPlugin );
下载代码:https://github.com/kenkozheng/HTML5_research/tree/master/Vue-Multipages-Webpack3
npm i npm run dev
浏览器访问http://localhost:8088/dist/page1.html和http://localhost:8088/dist/page2.html看看吧