在拉钩学习的笔记(二十五)webpack打包

基础:
进阶:
项目:
1、概述:webpack 简介
    Webpack = Web Package 是一个现代 JS 应用程序的 静态模块打包器(module bundler)  
        模块:模块化开发,可以提高开发效率,避免重复造轮子
        打包(bundler):将各个模块,按照一定的规则组装起来
    官网:https://webpack.js.org/
    特点:功能强大(打包、构建、发布 web 服务); 学习成本高
    构建(转换):把不支持的代码,转成支持的代码;构建过程 就是将源代码通过 编译、格式化校验、压缩等 转化成生产代码;
    打包(合并):将多个文件合并成一个文件
    Webpack 的功能
        将多个文件合并(打包),减少 HTTP 请求次数,从而提高生产环境的加载效率
        对代码进行编译,确保浏览器兼容性
        对代码进行压缩,减小文件体积,提高加载速度
        检测代码格式,确保代码质量
        提供热更新服务,提高开发效率
        针对不同环境,提供不同的打包策略
2、概述: Webpack 核心概念
    入口(Entry):打包时,第一个被访问的源码文件;
        默认是 src/index.js(可以通过配置文件指定); 
        Webpack 通过入口,加载整个项目的依赖
    出口(Output):打包后,输出的文件名称;默认是 dist/main.js(可以通过配置文件指定)
    加载器(Loader):专门用来处理一类文件(非 JS )的工具,webpack 默只能识别 JS,处理其他类型的文件,需要对应的loader;
        命名方式:xxx-loader(css-loader | html-loader | file-loader),以 -loader 为后缀;
        常用加载器:https://www.webpackjs.com/loaders/
    插件(Plugins):实现 loader 之外的其他功能,Plugin 是 Webpack 的支柱,用来实现丰富的功能
        命名方式: xxx-webpack-plugin(html-webpack-plugin)
        常用插件: https://www.webpackjs.com/plugins/
    模式(Mode):用来区分环境的关键字,不同环境的打包逻辑不同,因此需要区分
        三种模式 development(自动优化打包速度,添加一些调试过程中的辅助)-开发模式
                production(自动优化打包结果)-生产环境
                none(运行最原始的打包,不做任何额外处理)
    模块(Module):webpack 中模块概念比较宽泛(一切皆模块) js模块、一段css、一张图片、一个字体文件、……
        详情:https://www.webpackjs.com/concepts/modules/
    依赖图(Dependency Graph)
    Loader 和 Plugin 本质都是 npm 包
3、Webpack 最佳实践
    初始化项目:npm init -y
    安装 Webpack: npm install webpack webpack-cli -D
    创建入口文件: 默认地址 src/index.js
    执行打包(必须指定 mode):webpack ./src/index.js --output-path ./dist --mode=development
    * 安装命令需要调整(默认安装最新5版本):npm install webpack@4 -D 安装4版本
4、配置文件
    功能:用来简化命令行选项的
    默认配置文件名称是 webpack.config.js , 是以 ConmmonJS 规范进行组织的
    使用 Webpack 的过程中,大部分就是跟配置文件打交道的过程
    配置详情:https://www.webpackjs.com/configuration/
5、webpack 基础用法 打包 CSS
    - 打包逻辑
        打包 CSS 需要对应的 loader :
            css-loader 将css 转化为 js (将CSS输出到打包后的JS文件中)
            style-loader 把包含 CSS 内容的 JS 代码,挂载到页面的 <style> 标签当中
        在入口文件中引入 CSS (import "./css/main.css")   
        * 报错 currently no loaders are configured to process this file.  没有安装loader
        安装 (npm i css-loader style-loader -D)
        配置到 webpack.config.js 中: 1.匹配后缀名 test:/\.css$/i, 2.指定加载器 use:['style-loader','css-loader'], <--loader执行顺序: 先右后左(先下后上)
    - 打包 Less
        引入 less : import './css/main.less'
        安装: npm i less less-loader -D
        配置:匹配后缀名: test: /\.less$/i, ; 指定加载器: use: ['style-loader', 'css-loader','less-loader']
    - 打包成独立的 CSS 文件
        安装插件: npm install mini-css-extract-plugin -D
        引入插件(webpack.config.js):const 
        =require('mini-css-extract-plugin');
        替换 style-loader(use:['MiniCssExtractPlugin.loader','css-loader']: 将css打包到独立文件中
        配置插件(new MiniCssExtractPlugin()) plugin中
    - 添加样式前缀
        安装: npm install postcss-loader autoprefixer -D
        配置 webpack.config.js : use:['MiniCssExtractPlugin.loader','css-loader','postcss-loader']
        * 注意执行顺序
        新建 postcss.config.js 文件: plugins:[require('autoprefixer')]
        配置需要兼容的浏览器:package.json 中指定 browserslist ; 详情参考: https://www.npmjs.com/package/browserslist
            // 指定浏览器的配置
            "browserslist": [
            "last 1 version",  // 最后一个版本
            "> 1%"            // 代表全球超过 1% 使用的浏览器
            ]
        * json文件中不能用注释
    - 格式校验
        安装: npm i stylelint stylelint-config-standard stylelint-webpack-plugin -D
            * stylelint :指定了代码的校验规则  https://stylelint.io/ 
                校验规则(number-leading-zero): line-height: .5;  ❌; line-height: 0.5;  ✔
            * stylelint-config-standard : 提供了一个具体的规则集 https://github.com/stylelint/stylelint-config-standard
            * stylelint-webpack-plugin : 允许webpack用stylelint对代码进行格式校验 https://webpack.docschina.org/plugins/stylelint-webpack-plugin
        引入(webpack.config.js): const StylelintPlugin = require ('stylelint-webpack-plugin');
        配置插件(plugin): new StylelintPlugin()
        指定校验规则: 在 package.json 中指定 stylelint
            "stylelint": {
                "extends": "stylelint-config-standard",
                // 后续为扩展配置 (如果不需要自定义规则,可以忽略 rules)
                "rules" : { 
                    // 小数点从不显示前面的 零
                  "number-leading-zero": "never"
                }
            }
    - 压缩 CSS
        安装: npm install optimize-css-assets-webpack-plugin -D
        引入: OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
        配置: new OptimizeCssAssetsPlugin()
6、webpack 基础用法 打包 HTML
    html-webpack-plugin : 
        生成 HTML 文件(用于服务器访问),并在 HTML 中加载所有的打包资源
        指定 HTML 模板、设置 HTML 变量、压缩 HTML
    安装: npm i html-webpack-plugin -D
    引入: HtmlWebpackPlugin = require('html-webpack-plugin')
    配置: https://www.npmjs.com/package/html-webpack-plugin
        new HtmlWebpackPlugin({
            // 指定打包后的文件名称
            filename: 'index.html',
            // 用来指定生成 HTML 的模板
            template: './src/index.html',
            // 指定 HTML 中使用的变量
            title: 'Webpack Demo',
            // 压缩
            minify: {
                collapseWhitespace: true,
                keepClosingSlash: true,
                removeComments: true,
                removeRedundantAttributes: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true,
                useShortDoctype: true
              }
        })
        <!-- 指定标题中的变量 EJC 是一种 JS 的模板引擎 -->
        <title><%= htmlWebpackPlugin.options.title %></title>
        EJC 官网: https://ejs.bootcss.com/
        * 可以进行多个打包,再 new 一个新的 HtmlWebpackPlugin 就可以
7、webpack 基础用法 打包 JS
    - 编译JS :
        目的:将 ES6+ 转成 ES5, 从而保证, JS 在低版本浏览器的兼容性
        安装:npm install babel-loader @babel/core @babel/preset-env -D
        配置:https://www.npmjs.com/package/babel-loader
        在package.json 中添加
            "browserslist": [
                "last 1 version",
                "> 1%"
            ]
        * @babel/preset-env 只能转译基本语法(Promise 就不能转换)
        * @babel/polyfill(转译所有 JS 新语法) 
            安装:npm i @babel/polyfill -D
            入口文件中引入:import '@babel/polyfill'
        * core-js (按需转译 JS 新语法)
            安装: npm i core-js -D
            配置:按需加载 useBuilthIns:'usage'; 指定版本 corejs: 3
            {
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            ['@babel/preset-env', {
                                // 按需加载
                                useBuiltIns: 'usage',
                                corejs: 3,
                                // targets: "defaults"
                                // 指定兼容浏览器的版本
                                targets: {
                                    chrome: '58',
                                    ie: '9',
                                    firefox: '60',
                                    safari: '10',
                                    edge: '17'
                                }
                            }]
                        ]
                    }
                }
            }
    - 校验格式
        安装:npm i eslint eslint-config-airbnb-base eslint-webpack-plugin eslint-plugin-import -D
            eslint:(校验 JS 代码格式的工具)
                https://eslint.org/
            eslint-config-airbnb-base(最流行的JS 代码格式规范)
                https://www.npmjs.com/package/eslint-config-airbnb-base
                https://github.com/airbnb/javascript
            eslint-webpack-plugin(webpack 的 eslint 插件)
                https://www.npmjs.com/package/eslint-webpack-plugin
            eslint-plugin-import (用于在 package.json 中读取 eslintConfig 配置项
        配置:
            eslint-webpack-plugin: 
                const ESLintPlugin = require('eslint-webpack-plugin');  
                // plugin  设置
                new ESLintPlugin({
                    fix: true
                })
            eslintConfig (packagejson): "eslintConfig": {"extends":"airbnb-base"}
        报错: // eslint-disable-next-line  禁用下一行检查
8、webpack 基础用法 打包图片
    file-loader: 将用到的图片复制到输出目录,过滤掉不用的图片
        安装: npm install file-loader -D
        网址: https://www.npmjs.com/package/file-loader
        将 CSS 打包成独立的文件,处理 CSS 中的图片路径(例如:背景图片加载失败)
            rulse css
            loader: MiniCssExtractPlugin.loader,
            options: {
                publickPath: '../'  // 为背景图片添加指定路径
            }
            rules:
            {
                test: /\.(png|gif|jpe?g)$/i,
                use: {
                    loader: 'file-loader'
                }
            },
    url-loader : 是 file-loader 的升级版,如果图片小于配置大小,会转成 base64 字符串;
        转成 base64 字符串后,图片会跟 js 一起加载(减少图片的请求次数)
        安装: npm i url-loader -D
        网址: https://www.npmjs.com/package/url-loader
        rules :
            test: /\.(png|gif|jpe?g)$/i,
                use: {
                    loader: 'url-loader',
                    options: {
                        // 指定图片大小,小于该数值的图片,会被转成 base64
                        limit: 8 * 1024,    // 8 kb 
                        // [name] 是图片原来的名称
                        // [ext] 是图片原来的后缀名
                        name: "image/[name].[ext]",
                        // url-loader 默认采用 ESM 规范进行解析,但是 html-loader 引入图片使用的是 Common JS 规范
                        // 解决: 关闭 url-loader 默认的 ESM 规范,强制 url-loader 使用 Commonjs 规范进行打包
                        esModule: false
                    }
                }
        * base64 格式: data:(协议)[<mediatype>][;base64],(媒体类型和编码)<data>(文件内容)
    html-loader: 将 HTML 导出为字符串(负责引入 img ,从而能被 url-loader 进行处理
        网址: https://www.npmjs.com/package/html-loader
        安装: npm install html-loader -D 
        配置: test: /\.(htm|html)$/i,
                use: {
                    loader: 'html-loader', 
                    // webpack 4 只需要在 url-loader 配置 esModule: false
                    // webpack 5 需要 url-loader 中也配置 esModule: false
                    options: {
                        esModule: false
                    }
                }
        问题: html-loader 与 html-webpack-plugin 的冲突
            原因: htmlWebpackPlugin 会检查目标文件是否已经有loader处理,如果有其他loader处理,htmlWebpackPlugin 不会再使用 lodash.template 去处理 ejs 语法
            解决: 将 htmlWebpackPlugin 中,模板文件的后缀名改为.ejs(非.html),在引用的时候,用模板<img src="<%= require('./image/weixin.png') %>">
        * 如果html文件里没有使用ejs语法,就可以使用html-loader;如果使用了 ejs 的话,不用html也可以正常加载
9、webpack 基础用法 打包字体
    字体文件下载: https://www.iconfont.cn
    file-loader: 
        test:/\.(eot|svg|ttf|woff|woff2)$/i
        use: {
            loader: 'file-loader',
            options: {
                name: 'font/[name].[ext]'
            }
        }
    copy-webpack-plugin: 不需要处理的其他文件,可以直接复制到输出目录 https://www.npmjs.com/package/copy-webpack-plugin
        安装: npm install -D copy-webpack-plugin 
        引入: const CopyWebpackPlugin
        配置: new CopyWebpackPlugin({
                    patterns: [{
                        from: "src/public",
                        to: "public"
                    }]
                })
    clean-webpack-plugin(每次打包前,先删除历史文件)
        网址: https://www.npmjs.com/package/clean-webpack-plugin
10、webpack 基础用法 资源模块
    功能: 资源模块是一种模块类型,它允许使用资源文件,而无需配置额外的 loader;
        资源文件:字体、图片、图标、HTML……;
        不用 file-loader、url-loader 也能加载图片和字体
    详情: https://webpack.docschina.org/guides/asset-modules
    Webpack 4
        raw-loader: 将文件导入为字符串
        file-loader: 将文件发送到输出目录
        url-loader: 将文件发送到输出目录,或转为 Data URL 内联到 bundle 中
    Webpack 5
        asset/resource 发送一个单独的文件并导出 URL(之前通过使用 file-loader 实现)
        asset/inline   导出一个资源的 data URL(之前通过使用 url-loader 实现)
        asset/source   导出资源的代码(之前通过使用 raw-loader 实现)
        asset          在导出一个 data URL 和发送一个单独的文件之间自动选择(url-loader)
        test: /\.(eot|svg|ttf|woff|woff2)$/i,
        type: 'asset',
        parser: {
            dataUrlCondition: {
                maxSize: 8 * 1024
            }
        },
        generator: {
            filename: "font/[name][ext]"
        }
11、webpack 基础用法 开发服务器
    webpack-dev-server
        作用: 发布 web 服务,提高开发效率
        详情: https://www.npmjs.com/package/webpack-dev-server  
        官网: https://webpack.docschina.org/configuration/dev-server
        使用: Webpack 4 : webpack-dev-server ...  Webpack 5 : webpack serve ...
        安装: npm i -D webpack-dev-server
        热更新: Webpack 4 : hot: true         Webpack 5  liveReload: true (禁用 hot)  target: "web"  (热更新只适用于 web 相关的 targets)
        proxy: 配置接口代理,解决 webpack-dev-server 下,访问接口的跨域问题
    devServer: {
        static: {
            directory: resolve(__dirname, 'dist'),
        },
        // 启用 gzip 压缩
        compress: true,

        // 端口号
        port: 9200,
        // 启动自动更新(禁用 hot)
        liveReload: true,
        // 配置代理: 解决接口跨域问题
        proxy: {
            // http://localohost:9200/api
            '/api': {
                // http://localohost:9200/api/users => https://api.github.com/api/users
                target: 'https://api.github.com',
                // http://localohost:9200/api/users => https://api.github.com/users
                pathRewrite: {
                    '^/api': ""
                },
                // 不能使用 localhost:9200 作为 github 的主机名
                changeOrigin: true
            }
        }
    },
    target: "web",
12、 Webpack 进阶 区分打包环境
    - 通过环境变量区分
        webpack --env.production
            命令行中设置环境变量: Webpack 4: webpack --env.production    Webpack 5: webpack --env production
        webpack.config.js 中判断 env
            读取环境变量 env.production ; 根据环境变量指定不同的配置
    - 通过配置文件区分
        webpack.dev.conf.js
        webpack.prod.conf.js
        执行打包时,指定配置文件(webpack --config webpack.[dev|prod].conf.js)
    - 详情: https://www.webpackjs.com/guides/environment-variables/
13、 Webpack 进阶 自定义 plugin
    Webpack 插件是一个具有 apply 方法的 JavaScript 对象。 apply 方法会被 webpack compiler 调用,并且在整个编译生命周期都可以访问到 compiler 对象
    原理: 通过在生命周期的钩子中挂载函数,来实现功能扩展
    详情: https://webpack.docschina.org/concepts/plugins/
    生命周期: 就是整个生命过程中的关键节点 初始化 -> 挂载 -> 渲染 -> 展示 -> 销毁
    钩子: 钩子是提前在可能增加功能的地方,埋好(预设)一个函数
        常用钩子: https://www.webpackjs.com/api/compiler-hooks/
    environment => compile => compilation => emit => afterEmit => dene
        环境就绪 => 编译开始 =>   编译完成   => 输出之前 => 输出之后 => 打包完成
14、 Webpack 进阶 自定义 loader
    loader 本质上就是一个 ESM 模块,它导出一个函数,在函数中对打包资源进行切换
    声明一个读取 markdown (.md) 文件内容的 loader
        marked( 将 markdown 语法转成 html) 
        loader-utils(接受 loader 的配置项)
15、 Webpack 进阶 代码分离(Code Splitting)
    多入口打包: 配置 entry 加载多个入口文件
        entry 后面写成对象: {index:'./src/index.js',about:'./src/about.js'}
        output.filename 不能写成固定名称,否则报错 [name].bundle.js
        HtmlWebpackPlugin 不同页面加载各自的 bundle : chunks:['index']  chunks:['about']
    提取公用模块: optimization.splitChunks.chunks:all
        如果一个页面都用到了一个公共文件(例如jQuery),每个页面都将公共文件打包一次是不合理的。更好的办法是将公共文件提取出来
    动态导入: 按需加载 | 预加载
        懒加载: 默认不加载,事件触发后才加载; webpackChunkName.'加载名称'
        预加载: 先等待其他资源加载,浏览器空闲时,再加载; webpackPrefetch: true ; 移动端有兼容问题
16、 Webpack 进阶 源码映射(Source Map)
    是一种源代码与构建后代码之间的映射技术; 通过.map文件,将构建后的代码与源代码之间建立映射关系
    用 Source Map 的原因: 构建后的代码,出了问题之后不好定位,有了它之后,可以快速定位问题代码
    生成: devtool:'映射模式'
        不同的映射模式的报错定位效果和打包执行速度不同
        Webpack 4中,一共有13种不同的映射模式
        Webpack 5中,一共有26种不同的映射模式
    开发环境: eval-cheap-module-source-map
    生产环境: none | nosources-source-map
17、 Webpack 进阶 删除冗余代码(Tree Shaking)
    前提: 使用 ES Moudles 规范的模块,才能执行 Tree Shaking ;Tree Shaking 依赖于 ESM 的静态语法分析
    生产模式: Tree Shaking 会自动开启
    开发模式: 
        usedExports :
            optimization.usedExports 标记没用的代码         /* unused harmony export XXXX */
            terser-webpack-plugin 删除没用的代码       optimization.minimize:true (删除 unused harmony export XXXX 标记的代码;webpack 4需要单独安装,5无需安装)  https://www.npmjs.com/package/terser-webpack-plugin
            Tree Shaking 与 Source Map 存在兼容性问题: 
                devtool: source-map|inline-source-map|hidden-source-map|nosources-source-map
                eval 模式,将 JS 输出为字符串(不是 ESM 规范),导致 Tree Shaking 失效
        sideEffects
            副作用  无副作用:如果一个模块单纯的导入导出变量,那他就无副作用
                有副作用:如果一个模块还修改其他模块或者全局的一些东西,就有副作用 修改全局变量; 在原型上扩展方法; CSS的引入
            sideEffects 的作用: 把未使用但无副作用的模块一并删除(对于没有副作用的模块,未使用代码不会被打包,相当于压缩了输出内容)
            使用方法: 开启副作用(webpack.config.js)optimization.sideEffects: ture ;
                标识代码是否有副作用(package.json) "sideEffects": false(所有代码没有副作用) true(所有代码都有副作用) 数组(告诉 webpack 哪些模块有副作用,不删除) 
18、 Webpack 进阶 缓存
    Babel 缓存
        cacheDirectory: true(第二次构建时,会读取之前的缓存)
    文件资源缓存
        如果代码在缓存期内,代码更新后看不到实时效果
        方案: 将代码文件名称,设置为哈希命名,名称发生变化时,就加载最新的内容
    Webpack 哈希值
        [hash] 每次 Webpack 打包生成的 hash 值
        [chunkhash] 不同 chunk 的 hash 值不同-同一次打包可能生成不同的chunk
        [contenthash] 不同内容的 hash 值不同-同一个chunk 中可能有不同的内容
19、 Webpack 进阶 模块解析(resolve)
    resolve
        配置模块解析的规则
        alias: 配置模块加载的路径别名  {'@:'resolve('src')},
        extensions: 引入模块时,可以省略哪些后缀    extensions:[".js",".json"]
        https://www.webpackjs.com/configuration/resolve/
20、 Webpack 进阶 排除依赖(externals)
    externals 
        排除打包依赖项(防止对某个依赖项进行打包)
        一般来说,一些成熟的第三方库,是不需要打包的
        例如:jQuery, 我们可以在模板文件中直接引入 CDN 中的压缩
        https://www.webpackjs.com/configuration/externals/
21、 Webpack 进阶 模块联邦
    多个应用,可以共享一个模块(本地可以调用远程的模块)
    模块提供方:
        name: 当前应用名称(供调用方使用)
        filename: 打包后的文件名称(供调用方使用)
        exposes: 暴露模块(相当于 export 导出)
            模块名称:模块文件路径
    模块使用方:
        remote:导入模块(相当于 import)
            导入后的别名: "远程应用名称@远程地址/远程导出的文件名"
        import("导入后的别名/模块名称").then(//...)
        https://webpack.js.org/concepts/module-federation/
22、 Webpack项目 常规操作(项目部署)
    初始化项目(npm init -y)
    常规操作: npm i -D webpack webpack-cli html-webpack-plugin webpack-dev-server copy-webpack-plugin clean-webpack-plugin mini-css-extract-plugin css-loader style-loader postcss-loader autoprefixer babel-loader @babel/core @babel/preset-env
        webpack.config.js
    src: index.js  index.ejs
22、 Webpack项目 Webpack 中使用 Bootstrap
    https://getbootstrap.com/docs/5.0/getting-started/webpack/
    安装 Bootstrap   npm i Bootstrap @popperjs/core
    样式    npm i -D sass sass-loader  配置 sass 文件
    验证效果(导航菜单,轮播图)
22、 Webpack项目 Webpack 在 Vue 中的应用
    安装脚手架工具  npm install -g @vue/cli
    初始化 vue 项目  vue init webpack projectname
    运行 vue 项目 cd projectname    npm run dev
22、 Webpack项目 Webpack 在 React 中的应用
    安装脚手架工具: npm install -g creat-react-app
    初始化 React 项目: create-react-app projectname
    运行 React 项目: cd projectname        npm start
    弹出 webpack 配置: npm run eject
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值