webpack4搭建多页面应用以及代码复用

it2025-01-08  8

前言

在开发类似官网这类项目时,一般不会使用框架,1是因为框架体积大且官网这类项目业务逻辑比较少,基本上是静态页面,2 是不利于SEO,所以只能自己用webpack从头搭建,正好最近公司在做新的官网,因此在这里记录一下webpack4的一些配置和优化。

GitHub完整项目地址

1.多入口并自动生成html

entry: { index: "./src/js/index.js", // 首页 about: "./src/js/about.js", //关于我们 }, plugins: [ // 自动清空dist目录 new CleanWebpackPlugin(), // 设置html模板生成路径 new HtmlWebpackPlugin({ filename: 'index.html', template: './src/views/index.html', chunks: ['index'] }), new HtmlWebpackPlugin({ filename: 'about.html', template: './src/views/about.html', chunks: ['about'] }), ], // 编译输出配置 output: { // js生成到dist/js,[name]表示保留原js文件名 filename: 'js/[name.[hash].js', // 输出路径为dist path: path.resolve(__dirname, 'dist') }

** 注意:在打包生产环境时,需在output添加publicPath属性,否则无法解析到资源目录 **

output:{ ..., publicPath: './' }

当页面较多时,可以使用动态加载文件的方式来引入:

const fs = require("fs"); let htmlPlugins = []; const files = fs.readdirSync(path.resolve(__dirname, "../src/views")); htmlPlugins = files.map((item) => { return new HtmlWebpackPlugin({ filename: item, template: `./src/views/${item}`, chunks: [item.split(".")[0]], }); }); module.exports = { ...... ...htmlPlugins, }

entry也可以用同样的方式。

2. 热更新

安装依赖:

npm install webpack-dev-server --save-dev

添加配置:

devServer: { contentBase: "./dist", port: 8888, hot: true, },

3.编译es6

安装依赖:

npm install babel-loader @babel/core @babel/preset-env --save-dev npm install @babel/plugin-transform-runtime @babel/plugin-transform-modules-commonjs --save-dev npm install @babel/runtime --save

配置如下:

{ test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"], plugins: ["@babel/plugin-transform-runtime", "@babel/plugin- transform-modules-commonjs"], }, }, },

4.加载css和scss

安装依赖:

npm install style-loader css-loader --save-dev npm install sass-loader node-sass --save-dev

将CSS提取为独立的文件

npm install mini-css-extract-plugin --save-dev

添加配置:

rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.scss$/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"] } ]

5.打包css中的图片

安装url-loader

npm install url-loader --save-dev

增加配置:

rules: [ ..., { test: /\.(png|svg|jpg|gif|webp)$/, use: [ { loader: "url-loader", options: { // 图片输出的实际路径(相对于dist) outputPath: "images", // 当小于某KB时转为base64 limit: 0, name: "[name].[ext]", esModule: false, //高版本url-loader需添加这个属性 }, }, ], }, ]

6.加载html中的图片

安装依赖:

npm install html-loader --save-dev

添加配置:

rules:[ ..., { test: /\.(html)$/, use: [ { loader: "html-loader", options: { // 改版后配置项发生了变化,请参考GitHub attributes: true, minimize: true, }, }, ], }, ]

7.处理第三方库,以jQuery为例

安装依赖:

npm install jquery --save

引入后即可使用

import $ from 'jquery'

但如果项目中多个页面使用到,每个页面都引入会很麻烦,可以使用webpack的全局引入插件:

plugins: [ ..., new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", }), ]

之后在所有页面都能直接使用jquery而不用单独引入。

8.代码复用

开发多页面应用时经常会出现代码需要多处使用的情况,比如官网的头部和底部,而复制粘贴又太low,所以我们需要实现代码复用。 在这里使用到的是html-withimg-loader这个loader,这个loader可以代替html-loader解决html中的图片加载问题,而且支持代码复用。 安装依赖:

npm install html-withimg-loader --save-dev

添加配置:

module:{ //删除html-loader相关配置 rules:[ { test: /\.(html)$/i, loader: "html-withimg-loader", //解决html中使用img标签路径找不到问题 } ] }

复用语法如下:

<div> #include("./layout/top.html") <!--子页面将被引入,并且子页面中的img标签同样会进行处理--> </div>

那么就可以在页面中进行代码复用 如:index.html

<div> #include("../component/header.html") </div>

header.css和header.js需在使用到的页面的js文件中引入, 如:index.js

import "./header.js"; import "../css/header.scss";

需要注意的是,html-withimg-loader并不能打包音视频文件,因此html中的多媒体文件需要单独在对应js文件中引入: 如:index.js

import "../images/home/video1.mp4"; //处理视频文件

9.打包优化

9.1使用BundleAnalyzerPlugin插件打包结果可视化的插件

安装依赖:

npm install webpack-bundle-analyzer --save-dev

添加配置:

plugins:[ ..., new BundleAnalyzerPlugin({ analyzerPort: 8889, }) ]

9.2拆分模块

因为多个页面都会用到如jquery这样的第三方包,那么每个文件都会把jquery打包进去,导致体积过大,因为可以使用splitChunks来拆分模块,只打包一次:

optimization: { splitChunks: { cacheGroups: { vendor: { name: "vendor", test: /[\\/]node_modules[\\/]/, chunks: "all", priority: 10, // 优先级 }, }, }, },
最新回复(0)