构建webpack5.x 知识体系:4、基础之css优化

这是一个系列文的分享记录,本篇主要是webpack的基础之css\js优化,如我们在生产环境的时候,更需要考虑将样式分离出来,(因为打包的是一个js,css都在整个js中,这样包会很大),css的兼容性(postcss),不同的浏览器中的一些样式有兼容问题需要处理,压缩样式文件,使的css包变小,打包速度变快等操作,清除无用的css分享。

正式开始:

预备技能

基本nodejs知识和npm指令

注意:版本问题导致不同,本系列实战中用到的webpack版本是:"webpack": "^5.68.0","webpack-cli": "^4.9.2"

webpack-bundle-analyzer

打包性能分析的插件: webpack-bundle-analyzer

这个插件可以帮助我们分析webpack在打包过程中有哪些可以改进的地方。

npm地址: www.npmjs.com/package/web…

使用

1、安装

npm install --save-dev webpack-bundle-analyzer
复制代码

2、修改配置webpack.config.js

先引入

const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
复制代码

在plugins中配置:

plugins: [
    new BundleAnalyzerPlugin()
  ]
复制代码

3、运行webpack --progress

会自动打开浏览器,localhost:8888,或者127.0.0.1:8888在这个页面上,

image.png

抽离css

为什么抽离css

默认打包是,css是在js中的,这样js文件就会很大,如果这个发布到生产环境,

由于是js加载的时候才会动态插入样式到head里,会造成闪屏现象。

入口文件变大,项目启动缓慢。所以我们需要提取css,让他从js里抽离出来。

因为CSS的下载和JS可以并行,当一个HTML文件很大的时候,我们可以把CSS单独提取出来加载,这样就可以解决问题了。

使用思路:

    • 使用插件 mini-css-extract-plugin
    • 下载插件,new 插件,代替style-loader,使用
    • 建议 mini-css-extract-plugin 与 css-loader 一起使用。

1、安装

npm install  mini-css-extract-plugin --save-dev
复制代码

2、修改配置webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
复制代码

MiniCssExtractPlugin.loader代替 style-loader

plugin中 添加new 插件

new MiniCssExtractPlugin({
                filename: 'css/built.css'
            }),
复制代码

完整代码:

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
​
const config = (mode) => {
    return {
        // webpack 配置
        // 入口起点
        entry: './src/index.js',
        // 输出
        output: {
            //  输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
            path: resolve(__dirname, 'build'),
            // 输出ming
            filename: 'built.js'
        },
        // loader 配置
        module: {
            rules: [
​
                {
                    //匹配以css结尾的文件
                    test: /.css$/,
                    //采用css-loader进行处理,让webpack能够识别 
                    //单个loader使用loader属性
                    //loader: 'css-loader'
​
                    //多个loader处理一个文件,需要使用use
                    //use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
                    use: [
                        MiniCssExtractPlugin.loader, 
                        'css-loader']
​
​
                },
                {
                    //匹配以.less结尾的文件
                    test: /.less$/,
                    //  less-loader 讲less文件变成成css文件 (需要下载两个依赖 less和less-loder)
                    // css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
                    // style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
                    // use数组执行顺序是倒叙,就是先执行'style-loader',在执行'css-loader'在执行'style-loader'
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
                },
                {
                    //匹配以.scss结尾的文件
                    test: /.scss$/,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
                },
                {
                    // 处理图片 
                    // 问题:默认处理不了html中img图片
                    test: /.(jpe?g|png|gif|svg)$/,
                    type: "asset/resource",
​
                    generator: {
                        //与output.assetModuleFilename是相同的,这个写法引入的时候也会添加好这个路径
                        filename: '[name][ext]'
                    },
                },
                {
                    // 处理html
                    // 问题:默认处理不了html中img图片
                    test: /.html$/,
                    // 使用一个loader 就是要loader属性值为字符串,多个使用use 值为数组
                    // 需要html中的img图片 (负责引入img 在url-loader在处理)
                    loader: 'html-loader',
                    // html-loader打包图片无法显示的问题 关闭es6模块的解析, 使用commonjs模块解析
                    // options: {
                    //     esModule: false
                    // }
​
                }
            ]
        },
        // plugins 的配置 
        plugins: [
​
​
            // 功能:默认会创建一个空的HTML 自动会引入打包输出的所有资源(js/css)
            // 需要有结构的html文件
            new HtmlWebpackPlugin({
                // 复制 './index.html' 文件并自动会引入打包输出的所有资源(js/css)
                template: './index.html'
            }),
            new MiniCssExtractPlugin({
                filename: 'css/built.css'
            }),
            // 清除build文件夹
            new CleanWebpackPlugin()
        ],
​
​
        mode: 'development', //开发模式, //开发模式
        // mode: 'production', //生产模式
​
        // 开发服务器 devserver 用来自动化(自动编译 自动打开浏览器 自动刷新浏览器。。。)
        // 特点 指挥在内存中编译打包 不会有任何输出
        // 启动devServer 指令 为npx webpack-dev-server
        // 1、下载依赖 2、使用 启动devServer 指令 为npx webpack-dev-server
        devServer: {
            // npx webpack-dev-server 报错 把 contentBase改为 static 或者注释掉 /webpack5中不用配置contentBase了,注释掉后正常打包
            static: resolve(__dirname, 'build'),
            // 启动gzip压缩
            compress: true,
            // 端口号
            port: 8888,
            // 自动打开浏览器
            open: true,
            // 开启HMR功能
            hot: true,
            // 域名
            host: 'localhost',
            // 服务器代理 -->解决开发环境跨域问题
            proxy: {
                '/api': {
                    target: 'http://localhost:5000',
                    pathRewrite: {
                        '^/api': ''
                    }
                }
            }
        },
​
​
    }
}
module.exports = (env, argv) => {
    console.log('argv.mode=', argv.mode, "env:", env)
        // 这里可以通过不同的模式修改 config 配置
    return config(argv.mode);
}
复制代码

3、运行 webpack --progress

我们可以看到build文件夹下多了一个css文件夹,下边有一个built.css文件

image.png

整个css是所有的我们引入的css、less、sass的使用。

build.js打包的体积也变小了。

查看浏览器,样式也没有问题

image.png 每次编译都自动开启打包分析,就很烦~ 改为如下,只有我们想打开时就可以,在webpack.config.js中修改

new BundleAnalyzerPlugin({
                analyzerMode: 'disabled', // 不启动展示打包报告的HTTP服务
                generateStatsFile: true // 要生成stats.json 
            }),
复制代码

package.json中增加命令

​
        "analyzer":"webpack-bundle-analyzer --port 8888 ./build/stats.json"
复制代码

执行命令:npm run analyzer

CSS兼容性

  • 为了浏览器的兼容性,有时候我们必须加入-webkit,-ms,-o,-moz这些前缀

    • Trident内核:主要代表为IE浏览器, 前缀为-ms
    • Gecko内核:主要代表为Firefox, 前缀为-moz
    • Presto内核:主要代表为Opera, 前缀为-o
    • Webkit内核:产要代表为Chrome和Safari, 前缀为-webkit
  • 伪元素::placeholder可以选择一个表单元素的占位文本,它允许开发者和设计师自定义占位文本的样式。

所以我们需要webpack帮我们来补全css的兼容性,可以使用PostCSS处理CSS,在webpack中这里使用postcss-loader来处理,postcss-loader依赖postcss,postcss-preset-env把现代的CSS转换成大多数浏览器能理解的(帮助postcss识别环境从而加载对应的配置,从而使得代码兼容每一个浏览器的版本)

postcss-preset-env: 帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式

  • PostCSS Preset Env已经包含了autoprefixerbrowsers选项

1、安装

npm i postcss-loader postcss  postcss-preset-env --save-dev
复制代码

2、创建postcss.config.js

这里我们将postcss-loader的插件设置单独拿出来放到postcss.config.js中,让postcss-loader的配置更加简洁。当然也可以在webpack.config.js中配置。

postcss.config.js

let postcssPresetEnv = require('postcss-preset-env');
module.exports={
    plugins:[postcssPresetEnv({
        browsers: 'last 5 version'
    })]
}
复制代码

3、package.json中修改

帮助postcss 找到package.json 中browerslist 里边的配置,通过配置加载指定的css兼容性样式

package.json

"browerslist": {
    "development": [ // 设置弄得环境变量: process.env.NODE_ENV = 'development'
        "last 1 chrome version",
        "last 1 firefox version",
        "last 1 saferi version"
    ],
    "production": [ // 默认是看生产环境
        ">0.2%",
        "not dead",
        "not op_mini all"
    ]
   }
复制代码

4、修改配置webpack.config.js

   {
                    //匹配以css结尾的文件
                    test: /.css$/,
                    //采用css-loader进行处理,让webpack能够识别 
                    //单个loader使用loader属性
                    //loader: 'css-loader'
​
                    //多个loader处理一个文件,需要使用use
                    //use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
                    use: [
                        MiniCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader'
                    ]
​
​
                },
                {
                    //匹配以.less结尾的文件
                    test: /.less$/,
                    //  less-loader 讲less文件变成成css文件 (需要下载两个依赖 less和less-loder)
                    // css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
                    // style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
                    // use数组执行顺序是倒叙,就是先执行'style-loader',在执行'css-loader'在执行'style-loader'
                    use: [MiniCssExtractPlugin.loader, 'css-loader',
                        'postcss-loader', 'less-loader'
                    ]
                },
                {
                    //匹配以.scss结尾的文件
                    test: /.scss$/,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
                },
复制代码

5、修改index.less

#title{
    color: chocolate;
    opacity: 0.8;
    width: 100px;
    height: 100px;
    transform:rotate(25deg) ;
}
复制代码

6、运行webpack

image.png

压缩css

一般是在生产环境中这样操作,压缩css,从而减少包的大小,减少请求时间。

避坑:

webpack5不在使用optimize-css-assets-webpack-plugin。 这是因为optimize-css-assets-webpack-plugin 在webpack5中已不在友好支持

那使用啥呢?

使用 css-minimizer-webpack-plugin

webpack.docschina.org/plugins/css…

使用注意:

1、配置在「plugins」中,webpack编译就会在启动时使用这个插件。

2、而配置在 「optimization.minimizer」 中,就只会在「optimization.minimizer」这个特性开启时使用。

所以webpack推荐,像压缩类的插件,应该配置在「optimization.minimizer」数组中。

以便于通过「optimization.minimizer」统一控制。 (生产环境会默认开启minimizer)

使用:

1、安装

npm i css-minimizer-webpack-plugin -D
复制代码

2、修改配置wepack.config.js中optimization.minimizer

​
optimization: {
        minimizer: [
            new CssMinimizerWebpackPlugin(),
​
        ],
        minimize: true, // 如果还想在开发环境下启用 CSS 优化,请将 optimization.minimize 设置为 true:
        }
复制代码

3、运行npm run build

编译成功

我们可以看到build/css/built.css 文件内容压缩

image.png

查看浏览器也没有问题

清除无用的CSS

在没有使用到的css清除掉,使用:purgecss-webpack-plugin

www.npmjs.com/package/pur…

使用

1、安装

npm i purgecss-webpack-plugin --save-dev
复制代码

2、修改配置webpack.config.js

const { resolve } = require('path');
const PurgecssPlugin = require("purgecss-webpack-plugin");
const glob = require('glob')
const PATHS = {
    src: resolve(__dirname, 'src')
}
复制代码
 plugins: [
  
   new PurgecssPlugin({
    paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),
   })
  ]
复制代码

3、修改index.css 中添加无用的样式

html,
body {
    padding: 0;
    margin: 0;
    background-color: cadetblue;
}
​
.other {
    padding: 0;
    margin: 0;
    background-color: cadetblue;
    display: flex;
    width: 100px;
    height: 100px;
}
复制代码

4、运行编译 webpack

我们可以看到build/css/built.css

中 删掉了 .other

image.png

感谢

到此,本篇介绍到此结束,之后将陆续整理 webpack 知识体系的内容分享,尽情期待,感谢您的阅读~~

猜你喜欢

转载自juejin.im/post/7069587683491708965