前言在实际开发需求中,我们可能无法使用单页面开发框架(如vue、react),这些需求主要基于SEO视角(当然,server-可以使用siderendering来解决,这里我们不考虑),这时候我们需要进行传统模式的前端开发。传统模式下会有css兼容和压缩、icon图片base64减少http请求、公共代码引入、js模块化等基础问题。关于wepack多页打包的资料和文档很多。遇到问题不要慌张,可以上网或者看官方文档(webpackdocuments-portal)。本文基于最新版webpack实现多页面打包。它不仅解决了上述基本问题,还增加了本地服务、自修改更新、自动引入公共代码等实用功能。本文中的webpack打包框架已经开源到github。欢迎大家入手(git-portal)。下面我们采用面向功能的webpack5多页面打包配置介绍。功能配置1.初始化webpacknpminitnpminstallwebpackwebpack-cli-g//-g换成--save-dev在本地安装webpack-cliinit2,图片文件等文件处理,webpack5集成到asset模块中。之前使用file-loader、url-loader和raw-loader这三个assets/resources将资源分成单独的文件并导出url,也就是之前的file-loader.asset/inlineexportsresources中的功能形式为dataURL(url(data:)),以及前面url-loader.asset/source的功能将资源导出为源代码(sourcecode)。之前的raw-loader函数。Asset自动选择导出为单独文件或dataURL形式(默认8KB)。以前,url-loader设置资产大小限制来限制实现。配置webpack.config.jsmodule:{rules:[{test:/\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,type:"asset",generator:{//输出文件名filename:'static/[hash][ext][query]'}}]}//也可以限制处理的大小,这里使用默认值3,处理html文件,为了不压缩后台绑定好友的操作,在html中处理图标和资源webpack.config.jsmodule:{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.jsconstcssMinimizerPlugin=require('css-minimizer-webpack-plugin');constMiniCssExtractPlugin=require("mini-css-extract-plugin");conststylesHandler=MiniCssExtractPlugin.loader;plugins:[newCssMinimizerPlugin()//csscompression],module:{rules:[{test:/\.(js|jsx)$/i,loader:"babel-loader",},{test:/\.css$/i,use:[stylesHandler,"css-loader","postcss-loader"],}]}5.公共代码处理,这里是当多个页面(>=2)有公共import时的处理,然后做一个包导入到多个页面,从而省钱,减少http请求自动导入公共文件,下面说明。constMiniCssExtractPlugin=require("mini-css-extract-plugin");plugins:[//在文件中合并cssnewMiniCssExtractPlugin({filename:'css/[name]/[name].[hash].css'}),//拷贝静态资源库newCopyPlugin({patterns:[{from:path.resolve(__dirname,'static'),to:'static'}],})]optimization:{splitChunks:{cacheGroups:{//packagepublicmodulecommons:{//initial表示提取入口文件的公共部分chunks:'initial',//表示提取公共部分的最小文件数minChunks:2,//表示提取common部分的最小大小minSize:0,//提取的文件名为name:'commons'}}}}6.工程配置入口文件和入口模板wepack.batch.entry.js(creation)constpath=require('路径')constglob=require('glob')constHtmlWebpackPlugin=require("html-webpack-plugin");constpublicPath='./'//入口文件constentry={}//入口文件对应模板constentryTemplate=[]exports.entry=()=>{seekAllFile()setEntryTemplate()return{entry,entryTemplate}}//获取pages文件夹下的所有入口文件(支持无限制包套)constseekAllFile=(parent='pages/*')=>{constfileList=glob.sync(path.resolve(__dirname,parent))if(fileList.length>0){fileList.forEach(file=>{constregJs=file.match(/.*\/(.*js)/i)if(regJs!==null&®Js[1]){constjsName=regJs[1]constkey=jsName.match(/(.*).js/i)[1]entry[key]=publicPath+parent.replace(/\*/,'')+jsName}else{constparentPath=parent.replace(/\*/,'')constreg=newRegExp(parentPath+'(.*)','i')constfolder=file.match(reg)[1]if(!file.match(/.*\/(.*?)\..*/)){console.log(file)seekAllFile(parentPath+folder+'/*')}}})}else{return}}//设置入口文件的模块文件(附加功能)constsetEntryTemplate=()=>{Object.keys(entry).forEach(key=>{entryTemplate.push(newHtmlWebpackPlugin({template:entry[key].replace(/\.js/,'.html'),filename:key+'.html',chunks:[key],inject:'body',minify:false}))})}pages下的所有文件都会自动设置为入口和入口文件(支持无限嵌套),但需要的结构如下pages/index/index.jsindex.htmljs文件名与html文件名同级,所以入口文件为js,模板为htmlwebpack.config.jsconstbatch=require('./wepack.batch.entry')['entry']();{entry:batch.entry,plugins:[//入口文件对应的模板...batch.entryTemplate,]}7.自动导入public文件,前提是在根目录下创建一个automation文件夹,该目录下index.js中导入的资源会被导入到每个模板中webpack.automation.load.js(create)//自动导入公共文件(如reset.css)/***@desc:自动导入publicfiles-allTemplate*@param{Object}batch.entry入口文件*@param{Array}batch.entryTemplatetemplate*/exports.automation=(batch)=>{batch.entry['automations']='./automation/index.js'batch.entryTemplate.forEach(item=>{item.userOptions.chunks.unshift('automations')item.userOptions.chunksSortMode='manual'})}webpack.config.jsconstbatch=require('./wepack.batch.entry')['entry']();constautoLoad=require('./webpack.automation.load')//自动导入automation/index.js中的内容——可自由配置设置autoLoad.automation(batch)automation/index.jsimport'../common/css/reset.css'这样每个入口文件模板都会导入reset.css。核心功能是配置HtmlWebpackPlugin的chunks8,原生服务和修改自更新webpack.config.jsconst{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,打开:true,port:8080,},plugins:[//清除生成文件夹在buildnewCleanWebpackPlugin(),]9,package.json"scripts":{"init":"webpackinit","test":"webpackserve--modedevelopment","build":"webpack--mode=production--node-env=production","build:dev":"webpack--mode=development","build:prod":"webpack--mode=production--node-env=production","watch":"webpack--watch","serve":"webpackserve--modedevelopment","dev":"webpackserve--模式开发》},webpack5多页面打包的基本配置如上,本文demo已经开源到github(git-传送门),如有任何使用问题,请在git上提问或issue
