在开发类似官网这类项目时,一般不会使用框架,1是因为框架体积大且官网这类项目业务逻辑比较少,基本上是静态页面,2 是不利于SEO,所以只能自己用webpack从头搭建,正好最近公司在做新的官网,因此在这里记录一下webpack4的一些配置和优化。
GitHub完整项目地址
** 注意:在打包生产环境时,需在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也可以用同样的方式。
安装依赖:
npm install webpack-dev-server --save-dev添加配置:
devServer: { contentBase: "./dist", port: 8888, hot: true, },安装依赖:
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"], }, }, },安装依赖:
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"] } ]安装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需添加这个属性 }, }, ], }, ]安装依赖:
npm install html-loader --save-dev添加配置:
rules:[ ..., { test: /\.(html)$/, use: [ { loader: "html-loader", options: { // 改版后配置项发生了变化,请参考GitHub attributes: true, minimize: true, }, }, ], }, ]安装依赖:
npm install jquery --save引入后即可使用
import $ from 'jquery'但如果项目中多个页面使用到,每个页面都引入会很麻烦,可以使用webpack的全局引入插件:
plugins: [ ..., new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", }), ]之后在所有页面都能直接使用jquery而不用单独引入。
开发多页面应用时经常会出现代码需要多处使用的情况,比如官网的头部和底部,而复制粘贴又太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"; //处理视频文件安装依赖:
npm install webpack-bundle-analyzer --save-dev添加配置:
plugins:[ ..., new BundleAnalyzerPlugin({ analyzerPort: 8889, }) ]因为多个页面都会用到如jquery这样的第三方包,那么每个文件都会把jquery打包进去,导致体积过大,因为可以使用splitChunks来拆分模块,只打包一次:
optimization: { splitChunks: { cacheGroups: { vendor: { name: "vendor", test: /[\\/]node_modules[\\/]/, chunks: "all", priority: 10, // 优先级 }, }, }, },