前言
在理论开发要求中咱们可能无奈是应用单页面开发框架(例如vue,react),这些要求次要是基于SEO角度登程(当然能够应用服务端渲染解决,这里咱们不思考),这时候咱们就须要进行传统模式的前端开发,传统模式下会有css兼容与压缩,icon图片base64化缩小http申请,公共代码引入,js模块化等根底问题。对于wepack多页面打包的材料文档很丰盛,理论遇到问题不要惊恐能够去网上查问或者去看看官网文档(webpack文档-传送门)。本篇文章是基于最新版本的webpack来实现多页面打包的,不仅解决了上述根底问题还减少了本地服务,批改自更新,公共代码主动引入等实用功能。本文的webpack打包框架已开源至githua欢送大家的start(git-传送门)
上面咱们采纳已性能为导向的webpack5多页面打包配置介绍
性能配置篇
1、初始化webpack
npm initnpm install webpack webpack-cli -g // -g 更换为 --save-dev 是本地装置webpack-cli init
2、图片文件及其他文件解决,webpack5集中到了asset模块, 之前应用file-loader、url-loader、raw-loader三个
asset/resource 将资源宰割为独自的文件,并导出url,就是之前的 file-loader的性能.asset/inline 将资源导出为dataURL(url(data:))的模式,之前的 url-loader的性能.asset/source 将资源导出为源码(source code). 之前的 raw-loader 性能.asset 主动抉择导出为独自文件或者 dataURL模式(默认为8KB). 之前有url-loader设置asset size limit 限度实现。
配置
webpack.config.js
module: { rules: [ { test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, type: "asset", generator: { // 输入文件名 filename: 'static/[hash][ext][query]' } } ]}// 还能够限度解决的大小,这里应用了默认值
3、解决html文件,为了后盾敌人好绑定不进行压缩操作,解决html里icon与资源
webpack.config.js
module: { rules: [ { test: /\.html$/, loader: 'html-loader', options: { minimize: false, // html不解决link\script标签(为了引入动态资源不hash) sources: { list: [ '...', { tag: 'script', attribute: 'src', type: 'src', filter : () => false, }, { tag: 'link', attribute: 'href', type: 'src', filter : () => false, } ] } } } ]}
4、解决js、css进行兼容与压缩
webpack.config.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');const MiniCssExtractPlugin = require("mini-css-extract-plugin");const stylesHandler = MiniCssExtractPlugin.loader;plugins: [ new CssMinimizerPlugin() // css压缩],module: { rules: [ { test: /\.(js|jsx)$/i, loader: "babel-loader", }, { test: /\.css$/i, use: [stylesHandler, "css-loader", "postcss-loader"], } ]}
5、公共代码解决,这里解决的是当多个页面(>=2)有独特引入的话做一次打包引入到多页面,从而节省开支缩小http申请。主动引入公共文件会在下边解说。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");plugins: [ // 合并文件内css new MiniCssExtractPlugin({ filename: 'css/[name]/[name].[hash].css' }), // 复制动态资源库 new CopyPlugin({ patterns: [ { from: path.resolve(__dirname, 'static'), to: 'static' } ], })]optimization: { splitChunks: { cacheGroups: { //打包公共模块 commons: { //initial示意提取入口文件的公共局部 chunks: 'initial', //示意提取公共局部起码的文件数 minChunks: 2, //示意提取公共局部最小的大小 minSize: 0, //提取进去的文件命名 name: 'commons' } } }}
6、工程化配置入口文件及入口模板
wepack.batch.entry.js (创立)
const path = require('path')const glob = require('glob')const HtmlWebpackPlugin = require("html-webpack-plugin");const publicPath = './'// 入口文件const entry = {}// 入口文件对应的模板const entryTemplate = []exports.entry = () => { seekAllFile() setEntryTemplate() return { entry, entryTemplate }}// 失去pages文件夹下所有入口文件(反对有限嵌套)const seekAllFile = (parent = 'pages/*') => { const fileList = glob.sync(path.resolve(__dirname, parent)) if (fileList.length > 0) { fileList.forEach(file => { const regJs = file.match(/.*\/(.*js)/i) if (regJs !== null && regJs[1]) { const jsName = regJs[1] const key = jsName.match(/(.*).js/i)[1] entry[key] = publicPath + parent.replace(/\*/, '') + jsName } else { const parentPath = parent.replace(/\*/, '') const reg = new RegExp(parentPath + '(.*)', 'i') const folder = file.match(reg)[1] if (!file.match(/.*\/(.*?)\..*/)) { console.log(file) seekAllFile(parentPath + folder + '/*') } } }) } else { return }}// 设置入口文件的模板文件(附加性能)const setEntryTemplate = () => { Object.keys(entry).forEach(key => { entryTemplate.push(new HtmlWebpackPlugin({ template: entry[key].replace(/\.js/, '.html'), filename: key + '.html', chunks: [key], inject: 'body', minify: false })) })}
pages下的所有文件会被主动设置问入口及入口文件(反对有限嵌套),然而要求构造如下
pages/index/index.js index.html js文件名与html文件名同名且同级
这样入口文件为js,模板为html
webpack.config.js
const batch = require('./wepack.batch.entry')['entry']();{ entry: batch.entry, plugins: [ // 入口文件对应的模板 ...batch.entryTemplate, ]}
7、主动引入公共文件,前提是在根目录创立automation文件夹,目录下index.js里的引入资源会被引入到个个模板中
webpack.automation.load.js (创立)
// 自动化引入公共文件(如reset.css)/** * @desc: 主动引入公共文件-所有模板 * @param { Object } batch.entry 入口文件 * @param { Array } batch.entryTemplate 模板 */exports.automation = (batch) => { batch.entry['automations'] = './automation/index.js' batch.entryTemplate.forEach(item => { item.userOptions.chunks.unshift('automations') item.userOptions.chunksSortMode = 'manual' })}
webpack.config.js
const batch = require('./wepack.batch.entry')['entry']();const autoLoad = require('./webpack.automation.load')// 主动引入automation/index.js中的内容-可自在配置autoLoad.automation(batch)
automation/index.js
import '../common/css/reset.css'
这样每个入口文件模板就会引入reset.css,性能外围就是配置HtmlWebpackPlugin的chunks
8、本机服务及批改自更新
webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');output: { path: path.resolve(__dirname, "dist"), filename: 'js/[name]/[name].[hash].js'},devServer: { contentBase: path.resolve(__dirname, "dist"), compress: true, hot: false, open: true, port: 8080,},plugins: [ // 革除生成文件夹在build new CleanWebpackPlugin(),]
webpack5的多页面打包根本配置就如上所述了,对于本文demo已开源至github(git-传送门),如果您有应用问题请您发问或者git上issues问题