[elpis] 前端工程化:webpack 配置

一、多页面构建(MPA)

前言:一个ssr的多页面(MPA)应用,利于seo,每个页面为单独模块

二、解析引擎 - 解析打包 webpack.base.js

入口配置

js 复制代码
 entry:{  // 多页面ssr应用
        "entry.page1":'./app/pages/page1/entry.page1.js',
        "entry.page2":'./app/pages/page2/entry.page2.js',
    },

loader解析配置

  1. vue=>vue-loader
  2. js=>bable-loader
  3. css=>style-loadercss-loaderless-loader
  4. png=>file-loader

plugins 插件配置

VueLoaderPlugin

  1. 处理.vue 文件,这个插件是必须的
  2. 他的职能是将你定义的其他规则复制并应用到.vue文件里 ,解析scrpt和style模块
  3. 例如,如果有一条匹配规则/.js$/的规则,那么他会应用到。vue文件中模块中

htmlWebpackPlugin

js 复制代码
 new HtmlWebpackPlugin({
            // 产物 (最终模版)输出路径
            filename:path.resolve(process.cwd(),'./app/public/dist/','entry.**.tpl'),
            // 指定要使用的模版文件
            template:path.resolve(process.cwd(),'./app/view/entry.tpl'),
            //要注入的代码块
            chunks:['entry.page1']
        }),

分包

把js文件打包成3种类型

  1. vendor:第三方lib库,基本不会改动,除非依赖版本升级
  2. common:业务组件代码的公共部分抽取出来,改动较少
js 复制代码
optimization:{
        splitChunks:{
            chunks:'all', //对同步异步都进行分割
            maxAsyncRequests:10,// 每次异步记载的最大并行请求数
            maxInitialRequests:10,// 入口点的最大并行请求数
            cacheGroups:{
                vendor:{// 第三方依赖库
                    test:/[\\/]node_modules[\\/]/,// 打包node_module中的文件
                    name:'vendor',// 模块名称
                    priority:20,// 优先级
                    enforce:true,// 强制执行
                    reuseExistingChunk:true//复用已有的公共 chunk
                },
                common:{// 公共模块
                    // test:/[\\/]common|widgets[\\/]/,
                    name:'common',// 模块名称
                    minChunks:2,// 被复用次数(被2处引用即被归为公共模块)
                    minSize:2,// 最小分割文件大小
                    priority:10,// 优先级
                    reuseExistingChunk:true//复用已有的公共chunk
                }
            }
        },
}

模版渲染

使用koa-nunjucks-2 插件

tpl模版地址为:/app/public/dist/entry.**.js

less 复制代码
注册 koaNunjucks 中间件
  const koaNunjucks = require('koa-nunjucks-2');
    app.use(KoaStatic(path.resolve(process.cwd(),'./app/public')))
    app.use(koaNunjucks({
      ext: 'tpl', // 模版文件
      path:  path.join(process.cwd(), './app/public'),
      nunjucksConfig: {
        noCache :true,  // 不使用缓存,每次重新编译
        trimBlocks: true // 去除换行符
      }
 渲染tpl模版
  ctx.render(`dist/entry.${ctx.params.page}`,{自定义传参})

webpack基础配置

css 复制代码
 entry:{
 "name":'入口文件地址'
 },
 modele:{ 
 rules:[{
...loader
}]
},
 output:{输出},
 plugins:[插件],
 reslove:{},
 optimization:{
 splitchunks 
},
 mode:''

生产 webpack.prod.js

利用缓存打包

js 复制代码
   optimization:{
        //使用TerserPlugin 的并发和缓存,提升压缩阶段的性能
        //清除console。log
        minimize:true,
        minimizer:[
            new TerserWebpackPlugin({
                cache:true, // 启用缓存来加速构建过程
                parallel:true,// 利用多核cpu的优势来加快压缩速度
                terserOptions:{
                    compress:{
                        drop_console:true// 去除console.log 内容
                    }
                },
                extractComments:false // 禁止提取注释到单独文件
            })
        ],
    }

多线程打包 js css

使用happyPack 多线程打包

css 缓存,压缩

使用MiniCssExtractPlugin提取css公共部分,有效利用缓存,使用CssMinimizerPlugin打包压缩css

开发 webpack.dev.js

js 复制代码
const webpackDevConfig = merge.smart(baseConfig,{
    mode:'development',
    // source-map 开发工具,呈现代码映射关系。便于开发过程中调试代码
    devtool:'eval-cheap-module-source-map',
    // 开发阶段 output 配置
    output:{
        filename:'js/[name]_[chunkhash:8].bundle.js',
        path:path.resolve(process.cwd(),"./app/public/dist/dev/"),// 存储路径
        publicPath:`http://${HOST}:${PORT}/public/dist/dev/`, // 外部资源公共路径
        globalObject:'this'
    },
    plugins:[
        // HotModuleReplacementPlugin 用于实现热模块替换 hmr
        // 模块热替换允许应用程序运行时替换模版
        // 极大的提升开发效率,因为能让应用程序一直保持运行状态
        new webpack.HotModuleReplacementPlugin({
            multStep:false
        })
    ]
})

热更新

hmr 热更新: 书写业务代码->监控文件改动-> 通知解析引擎解析打包压缩-> template 发送客户端 公共部分发送服务端-> 服务端通知客户端变化-> 客户端加载template和公共资源重新展示

devmiddleware 中间件(监控文件改动)

hotmiddleware 中间件(实现热更新通讯)

js 复制代码
app.use(webpackDevMiddleware(compiler,{
    writeToDisk:(filePath)=>filePath.endsWith('.tpl'),
    //资源路径
    publicPath:webpackDevConfig.output.publicPath,
    // headers 配置
    headers:{
        "Access-Control-Allow-Origin":'*',
        "Access-Control-Allow-Methods":'GET,POST,PUT,DELETE,PATCH,OPTIONS',
        "Access-Control-Allow-Headers":"Content-Type, X-Requested-With, Authorization"  
    },
    stats:{
        colors:true
    }
}))
const {PORT,HMR_PATH} = DEV_SERVER_CONFIG

app.use(webpackHotMiddleware(compiler,{
    path:`/${HMR_PATH}`,  // 与devmiddleware的publicPath组合成完整地址
    log:()=>{}
}))

补充: webpack5 自带的原生打包工具thread-loader 多线程打包

js 复制代码
rules: [{  
test: /.js$/,  
use: [  
{  
loader: 'thread-loader',  
options: { workers: os.cpus().length - 1 }  
},  
{  
loader: 'babel-loader',  
options: {  
presets: ['@babel/preset-env'],  
plugins: ['@babel/plugin-transform-runtime']  
}  
}  
]  
}]
相关推荐
llq_3502 小时前
用 Nginx 搭建前端本地预览环境
前端
Mintopia2 小时前
如何用 TypeScript 折腾出全排列之你不知道的 :“分布式条件类型”、“递归处理”
前端·javascript·typescript
十八朵郁金香3 小时前
深入理解 SSE:服务器发送事件及其在前后端中的实践
前端·javascript
加油乐3 小时前
Sass与Less的特性与区别
前端·css
鹏多多3 小时前
React自定义Hooks设计指南:从封装到复用
前端·javascript·react.js
JarvanMo3 小时前
在 Flutter 中正确处理文本缩放
前端
深蓝电商API3 小时前
HTML 解析入门:用 BeautifulSoup 轻松提取网页数据
前端·爬虫·python·beautifulsoup
excel3 小时前
JavaScript 运算符与 Vue 中的 1 << n 应用
前端
上单带刀不带妹3 小时前
Vue3 全局 API 转移详解
前端·javascript·vue.js·vue3·api