高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
2017-08-28 13:57
1016 查看
本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到!
运行编译
build 两个如此简单的两个页面, 耗时 6 秒多, 可以预见在实际开发中将面临 build 耗时长的问题. 并且我们看到 build 后的 js 文件达到 1.05MB 之大. 实际上, index.js 和 about.js 两者是有共用部分的, 这其中包括 jquery , vue, AdminLTE 这些基础组件. 本篇的主题就是介绍如何提取这部分共用的组件出来单独编译.
新建组件打包配置文件: webpack.dll.config.js
entry 当中, 指定哪些资源被视为共用组件
上面的配置将在当前目录下, 创建一个 dll 目录, 专门用来存放共用组件包 vendor.js, 并且生成一个 template.html, 这个 template.html 中包含对 vendor.js 的引用. template.html 将作为其他页面的基础模板使用, 这样一般静态页面就能够引用到 vendor.js 了.
我们来修改 webpack.config.js
DllReferencePlugin 通过读取 ./dll/vendor-manifest.json, 判断哪些资源引用被打包在共用组件包
index.html 和 about.html 以 ./dll/template.html 作为模板, 从而获取对 vendor.js 的引用
引入 CopyWebpackPlugin 这个插件, 负责将共用组件包依赖的资源文件拷贝到发布目录下, 同时过滤掉发布时不需要的文件: template.html 和 vendor-manifest.json
修改 package.json , 添加 dll 编译配置:
编译共用组件, 你可能在整个开发过程中, 只需要执行一次对共用组件的 build, 因为一般情况下, 我们很少会对它做改动, 这一点是我优化编译时间的关键.
编译静态页面, 这一次的耗时相对之前减少了 4 秒多.
是不是离幸福又近了一点, 源码位置: easydss-web-src/tree/blog_2
下一篇介绍在此基础之上, 引入饿了么前端组件框架
WEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2017
接上回 《高性能流媒体服务器EasyDSS前端重构(一)-从零开始搭建 webpack + vue + AdminLTE 多页面脚手架》
在上一篇博客中, 我们白手起家, 从零搭建了 webpack + vue + AdminLTE 多页面脚手架. 代码在这里: easydss-web-src , 我为第一篇博客建立了单独的分支blog_1, 并且我打算后面的系列都这样, 建立一个单独分支.
为什么要提取共用文件
我们已经创建了两个静态页面: index.html 和 about.html, 对应的入口 js 分别是 index.js 和 about.js.运行编译
npm run build
build 两个如此简单的两个页面, 耗时 6 秒多, 可以预见在实际开发中将面临 build 耗时长的问题. 并且我们看到 build 后的 js 文件达到 1.05MB 之大. 实际上, index.js 和 about.js 两者是有共用部分的, 这其中包括 jquery , vue, AdminLTE 这些基础组件. 本篇的主题就是介绍如何提取这部分共用的组件出来单独编译.
webpack.DllPlugin
类似于 Windows 中 DLL 动态库的概念, 在 webpack 2 当中, 引入了 DllPlugin. 借助这个插件, 我们能够把共用的组件 build 到一块, 生成 vendor.js, 然后在静态页面中, 引用这个 vendor.js.新建组件打包配置文件: webpack.dll.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const webpack = require('webpack'); const path = require('path'); function resolve(dir) { return path.resolve(__dirname, dir) } module.exports = { entry: { //提取共用组件, 打包成 vendor.js vendor: ['jquery', 'vue', 'vuex', 'babel-polyfill', 'font-awesome/css/font-awesome.css', 'admin-lte/bootstrap/css/bootstrap.css', 'admin-lte/dist/css/AdminLTE.css', 'admin-lte/dist/css/skins/_all-skins.css', 'admin-lte/bootstrap/js/bootstrap.js', 'admin-lte/dist/js/app.js'] }, output: { path: resolve('dll'), filename: 'js/[name].[chunkhash:8].js', library: '[name]_library' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.common.js', 'jquery$': 'admin-lte/plugins/jQuery/jquery-2.2.3.min.js' } }, module: { rules: [{ test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader?limit=10000&name=images/[name].[hash:8].[ext]' }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader?limit=10000&name=fonts/[name].[hash:8].[ext]' }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader?limit=10000&name=media/[name].[hash:8].[ext]' }] }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', "window.jQuery": 'jquery', "window.$": 'jquery' }), new webpack.HashedModuleIdsPlugin(), new CleanWebpackPlugin(['dll']), new webpack.DllPlugin({ path: resolve("dll/[name]-manifest.json"), name: "[name]_library", context: __dirname }), new HtmlWebpackPlugin({ filename: 'template.html', title: '<%= htmlWebpackPlugin.options.title %>', inject: 'head', chunks: ['vendor'], template: './src/template.html', minify: { removeComments: true, collapseWhitespace: false } }) ] };
entry 当中, 指定哪些资源被视为共用组件
上面的配置将在当前目录下, 创建一个 dll 目录, 专门用来存放共用组件包 vendor.js, 并且生成一个 template.html, 这个 template.html 中包含对 vendor.js 的引用. template.html 将作为其他页面的基础模板使用, 这样一般静态页面就能够引用到 vendor.js 了.
webpack.DllReferencePlugin
DllReferencePlugin 这个插件用来告诉 webpack , 哪些引用到的资源已经被打包在共用组件包当中, 从而避免再次被打包.我们来修改 webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const webpack = require('webpack'); const path = require('path'); require("babel-polyfill"); function resolve(dir) { return path.resolve(__dirname, dir) } module.exports = { //定义页面的入口, 因为js中将要使用es6语法, 所以这里需要依赖 babel 垫片 entry: { index: ['babel-polyfill', './src/index.js'], about: ['babel-polyfill', './src/about.js'] }, output: { path: resolve('dist'), // 指示发布目录 filename: 'js/[name].[chunkhash:8].js' //指示生成的页面入口js文件的目录和文件名, 中间包含8位的hash值 }, //下面给一些常用组件和目录取别名, 方便在js中 import resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.common.js', 'jquery$': 'admin-lte/plugins/jQuery/jquery-2.2.3.min.js', 'src': resolve('src'), 'assets': resolve('src/assets'), 'components': resolve('src/components') } }, module: { //配置 webpack 加载资源的规则 rules: [{ test: /\.js$/, loader: 'babel-loader', include: [resolve('src')] }, { test: /\.vue$/, loader: 'vue-loader' }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.less$/, loader: "less-loader" }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader?limit=10000&name=images/[name].[hash:8].[ext]' }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader?limit=10000&name=fonts/[name].[hash:8].[ext]' }, { test: /\.(swf|mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader?limit=10000&name=media/[name].[hash:8].[ext]' }] }, plugins: [ //引入全局变量 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', "window.jQuery": 'jquery', "window.$": 'jquery' }), new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./dll/vendor-manifest.json') }), new CopyWebpackPlugin([ { from: 'dll', ignore: ['template.html', 'vendor-manifest.json'] } ]), //编译前先清除 dist 发布目录 new CleanWebpackPlugin(['dist']), //生成视频广场首页, 在这个页面中自动引用入口 index --> dist/js/index.[chunkhash:8].js //以 src/index.html 这个文件作为模板 new HtmlWebpackPlugin({ filename: 'index.html', title: '视频广场', inject: true, // head -> Cannot find element: #app chunks: ['index'], template: './dll/template.html', minify: { removeComments: true, collapseWhitespace: false } }), //生成版本信息页面, 在这个页面中自动引用入口 about --> dist/js/about.[chunkhash:8].js //以 src/index.html 这个文件作为模板 new HtmlWebpackPlugin({ filename: 'about.html', title: '版本信息', inject: true, chunks: ['about'], template: './dll/template.html', minify: { removeComments: true, collapseWhitespace: false } }) ] };
DllReferencePlugin 通过读取 ./dll/vendor-manifest.json, 判断哪些资源引用被打包在共用组件包
index.html 和 about.html 以 ./dll/template.html 作为模板, 从而获取对 vendor.js 的引用
引入 CopyWebpackPlugin 这个插件, 负责将共用组件包依赖的资源文件拷贝到发布目录下, 同时过滤掉发布时不需要的文件: template.html 和 vendor-manifest.json
使用新的编译方式
因为新引入 CopyWebpackPlugin 插件, 首先, 我们安装它npm i copy-webpack-plugin --save-dev
修改 package.json , 添加 dll 编译配置:
{ "name": "easydss-web-src", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack --progress --hide-modules", "dll": "webpack --progress --hide-modules --config ./webpack.dll.config.js", "start": "webpack-dev-server --open", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "admin-lte": "^2.3.11", "babel-core": "^6.26.0", "babel-loader": "^7.1.1", "babel-polyfill": "^6.26.0", "babel-preset-es2015": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "clean-webpack-plugin": "^0.1.16", "css-loader": "^0.28.5", "file-loader": "^0.11.2", "font-awesome": "^4.7.0", "html-webpack-plugin": "^2.30.1", "less": "^2.7.2", "less-loader": "^4.0.5", "style-loader": "^0.18.2", "url-loader": "^0.5.9", "vue": "^2.4.2", "vue-loader": "^13.0.4", "vue-template-compiler": "^2.4.2", "vuex": "^2.3.1", "webpack": "^3.5.5", "webpack-dev-server": "^2.7.1" } }
编译共用组件, 你可能在整个开发过程中, 只需要执行一次对共用组件的 build, 因为一般情况下, 我们很少会对它做改动, 这一点是我优化编译时间的关键.
npm run dll
编译静态页面, 这一次的耗时相对之前减少了 4 秒多.
npm run build
是不是离幸福又近了一点, 源码位置: easydss-web-src/tree/blog_2
下一篇介绍在此基础之上, 引入饿了么前端组件框架
element-ui
获取更多信息
邮件:support@easydarwin.orgWEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2017
相关文章推荐
- 高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
- EasyDSS高性能流媒体服务器前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
- 高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui
- 高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui
- 高性能流媒体服务器EasyDSS前端重构(一)-从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
- 高性能流媒体服务器EasyDSS前端重构(一)-从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
- EasyDSS高性能流媒体服务器前端重构(三): webpack + vue + AdminLTE 多页面引入 element-ui
- EasyDSS高性能流媒体服务器前端重构(一):从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
- EasyDSS高性能流媒体服务器前端重构(五): webpack + vue-router 开发单页面前端实现按需加载
- EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本
- EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载
- 高性能流媒体服务器EasyDSS前端重构(四)- webpack + video.js 打造流媒体服务器前端
- 高性能流媒体服务器EasyDSS前端重构(四)- webpack + video.js 打造流媒体服务器前端
- EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问
- EasyDSS高性能流媒体服务器前端重构(四): webpack + video.js 打造流媒体服务器前端
- EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问
- EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问
- Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
- 详解webpack编译多页面vue项目的配置问题
- webpack2.X提取Vue文件中的css、less或者sass样式