基于 webpack2.x 的 vue2.x 的多页面站点

本贴最后更新于 2589 天前,其中的信息可能已经天翻地覆

依旧使用 vue-cli 来初始化我们的项目

然后修改主要目录结构如下:

├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── src │ ├── pages │ │ ├── boys │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ └── index.vue │ │ ├── goods │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ └── index.vue │ │ ├── index │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ └── index.vue │ │ └── sotho │ │ ├── index.html │ │ ├── index.js │ │ └── index.vue

编写每个页面

可以看到这里我们有 4 个单独的页面,分别是 boys,goods,index,sotho

首先看 boys 文件夹中的代码:

index.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vue3</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>

这个是我们要单独生成的页面,最后也是生成 index.html

index.vue

<style scoped> .boys { background-color: red; } </style> <template> <div id="app" class="boys"> boys got many things. </div> </template> <script> export default { name: 'boys' } </script>

这是我们的 vue 文件,可以看成一个组件,其实 .vue 文件你可以看成一个语法糖,最终会被 vue-loader 编译成 js,生成对应的 css,js,dom

index.js

import Vue from 'vue' import Index from './index.vue' Vue.config.productionTip = false new Vue({ el: '#app', template: '<Index/>', components: { Index } })

这就是主要文件了,这里执行 vue 的实例化,用法同在浏览器端页面中直接引入 vue.js 文件一样的含义

其他几个页面一样也是同理,具体可以见:

修改 webpack.config.js

由于 vue 中的配置使用了模块化管理,所以我们需要修改下面两个文件:

  • webpack.base.conf.js

我们需要修改 webpack.base.conf.js 的入口 entry,这是配置多入口文件的重点!
如果不懂多入口含义的化,建议去看下 webpack 的文档。

webpack.base.conf.js

... module.exports = { entry: { 'pages/boys/index': './src/pages/boys/index.js', //配置boys页面入口 'pages/goods/index': './src/pages/goods/index.js', //配置goods页面入口 'pages/index/index': './src/pages/index/index.js', //配置index页面入口 'pages/sotho/index': './src/pages/sotho/index.js', //配置sotho页面入口 }, ...
  • webpack.dev.conf.js

这里我们需要修改 plugins,它是个强大的即插即用的拓展。

我们使用 html-webpack-plugin 来生成我们的对于的页面。

... var HtmlWebpackPlugin = require('html-webpack-plugin') ... ... module.exports = merge(baseWebpackConfig, { ... plugins: [ new webpack.DefinePlugin({ 'process.env': config.dev.env }), new HtmlWebpackPlugin({ filename:'./pages/boys/index.html', //指定生成的html存放路径 template:'./src/pages/boys/index.html', //指定html模板路径 inject: true, //是否将js等注入页面,以及指定注入的位置'head'或'body' chunks:['pages/boys/index'] //需要引入的chunk(模块资源),不配置就会引入所有页面的资源(js/css),这是个很重要的属性,你可以不配置试试效果 }), new HtmlWebpackPlugin({ filename:'./pages/goods/index.html', template:'./src/pages/goods/index.html', inject: true, chunks:['pages/goods/index'] }), new HtmlWebpackPlugin({ filename:'./pages/index/index.html', template:'./src/pages/index/index.html', inject: true, chunks:['pages/index/index'] }), new HtmlWebpackPlugin({ filename:'./pages/sotho/index.html', template:'./src/pages/sotho/index.html', inject: true, chunks:['pages/sotho/index'] }), ... ] })

以上就是我们进行多页开发的主要配置项。

开发环境访问页面

运行 npm run dev,我们看下怎么访问我们的多页 vue 应用。

再来看下我们的 dom 结构是什么样:

页面里的 js 就是我们通过插件注入的,并且我们是通过指定 chunks 完成。

build

运行 npm run build

➜ vue2-x-multiple git:(master) ✗ npm run build > vue3@1.0.0 build /study/vue2-x-multiple > node build/build.js ⠋ building for production... Starting to optimize CSS... Processing static/css/pages/boys/index.19ebbc80a1c187989dbf02d03192e84e.css... Processing static/css/pages/goods/index.fe8f1bc39f33dce4c4d610c2326482c6.css... Processing static/css/pages/index/index.f6340f14071a89cf2b092da280ffaf8c.css... Processing static/css/pages/sotho/index.7415ffd3ef7b9d1a4398cba49927b12b.css... Processed static/css/pages/boys/index.19ebbc80a1c187989dbf02d03192e84e.css, before: 114, after: 44, ratio: 38.6% Processed static/css/pages/goods/index.fe8f1bc39f33dce4c4d610c2326482c6.css, before: 116, after: 46, ratio: 39.66% Processed static/css/pages/index/index.f6340f14071a89cf2b092da280ffaf8c.css, before: 92, after: 22, ratio: 23.91% Processed static/css/pages/sotho/index.7415ffd3ef7b9d1a4398cba49927b12b.css, before: 92, after: 22, ratio: 23.91% Hash: 2467c91090ccf4690865 Version: webpack 2.5.1 Time: 6319ms Asset Size Chunks Chunk Names static/css/pages/sotho/index.7415ffd3ef7b9d1a4398cba49927b12b.css.map 312 bytes 1 [emitted] pages/sotho/index static/js/vendor.d7548891d04d4f883b29.js 83.2 kB 0 [emitted] vendor static/js/pages/index/index.b2ce74f4155fb942a064.js 671 bytes 2 [emitted] pages/index/index static/js/pages/goods/index.7d0dda2791db2d3b1500.js 702 bytes 3 [emitted] pages/goods/index static/js/pages/boys/index.2c268b75ba9424211d79.js 699 bytes 4 [emitted] pages/boys/index static/js/manifest.f466ccb58b3271558be5.js 1.57 kB 5 [emitted] manifest static/css/pages/boys/index.19ebbc80a1c187989dbf02d03192e84e.css 44 bytes 4 [emitted] pages/boys/index static/css/pages/goods/index.fe8f1bc39f33dce4c4d610c2326482c6.css 46 bytes 3 [emitted] pages/goods/index static/css/pages/index/index.f6340f14071a89cf2b092da280ffaf8c.css 22 bytes 2 [emitted] pages/index/index static/css/pages/sotho/index.7415ffd3ef7b9d1a4398cba49927b12b.css 22 bytes 1 [emitted] pages/sotho/index static/js/vendor.d7548891d04d4f883b29.js.map 687 kB 0 [emitted] vendor static/js/pages/sotho/index.e706490d7c42ad8e4f73.js.map 5.55 kB 1 [emitted] pages/sotho/index static/js/pages/sotho/index.e706490d7c42ad8e4f73.js 674 bytes 1 [emitted] pages/sotho/index static/js/pages/index/index.b2ce74f4155fb942a064.js.map 5.55 kB 2 [emitted] pages/index/index static/css/pages/index/index.f6340f14071a89cf2b092da280ffaf8c.css.map 312 bytes 2 [emitted] pages/index/index static/js/pages/goods/index.7d0dda2791db2d3b1500.js.map 5.64 kB 3 [emitted] pages/goods/index static/css/pages/goods/index.fe8f1bc39f33dce4c4d610c2326482c6.css.map 338 bytes 3 [emitted] pages/goods/index static/js/pages/boys/index.2c268b75ba9424211d79.js.map 5.62 kB 4 [emitted] pages/boys/index static/css/pages/boys/index.19ebbc80a1c187989dbf02d03192e84e.css.map 333 bytes 4 [emitted] pages/boys/index static/js/manifest.f466ccb58b3271558be5.js.map 14.6 kB 5 [emitted] manifest ./pages/boys/index.html 386 bytes [emitted] ./pages/goods/index.html 389 bytes [emitted] ./pages/index/index.html 389 bytes [emitted] ./pages/sotho/index.html 389 bytes [emitted] Build complete. Tip: built files are meant to be served over an HTTP server. Opening index.html over file:// won't work.

进入 dist 目录,查看生成的页面

├── pages │ ├── boys │ │ └── index.html │ ├── goods │ │ └── index.html │ ├── index │ │ └── index.html │ └── sotho │ └── index.html └── static ├── css │ └── pages │ ├── boys │ │ ├── index.19ebbc80a1c187989dbf02d03192e84e.css │ │ └── index.19ebbc80a1c187989dbf02d03192e84e.css.map │ ├── goods │ │ ├── index.fe8f1bc39f33dce4c4d610c2326482c6.css │ │ └── index.fe8f1bc39f33dce4c4d610c2326482c6.css.map │ ├── index │ │ ├── index.f6340f14071a89cf2b092da280ffaf8c.css │ │ └── index.f6340f14071a89cf2b092da280ffaf8c.css.map │ └── sotho │ ├── index.7415ffd3ef7b9d1a4398cba49927b12b.css │ └── index.7415ffd3ef7b9d1a4398cba49927b12b.css.map └── js ├── manifest.f466ccb58b3271558be5.js ├── manifest.f466ccb58b3271558be5.js.map ├── pages │ ├── boys │ │ ├── index.2c268b75ba9424211d79.js │ │ └── index.2c268b75ba9424211d79.js.map │ ├── goods │ │ ├── index.7d0dda2791db2d3b1500.js │ │ └── index.7d0dda2791db2d3b1500.js.map │ ├── index │ │ ├── index.b2ce74f4155fb942a064.js │ │ └── index.b2ce74f4155fb942a064.js.map │ └── sotho │ ├── index.e706490d7c42ad8e4f73.js │ └── index.e706490d7c42ad8e4f73.js.map ├── vendor.d7548891d04d4f883b29.js └── vendor.d7548891d04d4f883b29.js.map

到此为止,一个简单的基于 vue2.x 的多页应用完成了。

升级

webpack.base.conf.js 中的 entry 入口都是手工写入,如果页面多的话这样肯定有问题。

所以我们通过如下的方式来自动完成这段代码:

var entryJS = glob.sync('./src/pages/**/*.js').reduce(function (prev, curr) { prev[curr.slice(6, -3)] = curr; return prev; }, {});

这里的 './src/pages/**/*.js' 我们按照一定的规则去匹配我们的入口 j s 即可。

生成的的是:

{ 'pages/boys/index': './src/pages/boys/index.js', 'pages/goods/index': './src/pages/goods/index.js', 'pages/index/index': './src/pages/index/index.js', 'pages/sotho/index': './src/pages/sotho/index.js' }

与我们想要的行为一致

同样我们也升级下我们的 webpack.dev.conf.js 中的 plugins

var htmls = glob.sync('./src/pages/**/*.html').map(function (item) { return new HtmlWebpackPlugin({ filename: './' + item.slice(6), template: item, inject: true, chunks:[item.slice(2, -5)] }); }); module.exports = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) }, // cheap-module-eval-source-map is faster for development devtool: '#cheap-module-eval-source-map', plugins: [ new webpack.DefinePlugin({ 'process.env': config.dev.env }), // https://github.com/glenjamin/webpack-hot-middleware#installation--usage new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new FriendlyErrorsPlugin() ].concat(htmls) })

生成的是:

HtmlWebpackPlugin { options: { template: './src/pages/boys/index.html', filename: './pages/boys/index.html', hash: false, inject: true, compile: true, favicon: false, minify: false, cache: true, showErrors: true, chunks: [ 'pages/boys/index' ], excludeChunks: [], title: 'Webpack App', xhtml: false } }
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 1 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 254 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...