• Webpack


    Webpack

    Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
    会以一个文件或多个文件作为打包的入口

    Webpack五个核心概念

    1. entry(入口)
      从哪个文件开始打包
    2. output(输出)
      打包输出到哪里,如何命名
    3. loader(加载器)
      webpack本身只处理js.json等资源,
      其他资源需要借助loader,webpack才能解析
    4. plugins(插件)
      扩展webpack的功能
    5. mode(模式)
      开发模式:development
      生产模式:production

      webpack配置文件

      在项目根目录名字为webpack.config.js
        // CommonJS语法  模块化规范
    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
        mode: 'development', // 模式
        entry: path.join(__dirname,'src','index.js'),
        output: {
            path: path.resolve(__dirname,'dist'),//绝对路径
            filename: 'bundle.js' //输出文件的名字
        },
        module: {
            rules: []
        },
        plugins:[
            new HtmlWebpackPlugin({
                template: path.join(__dirname,'src', 'index.html'),
                filename: 'index.html'
            })
        ],
        devServer: {
            port: 8083,
            static: path.join(__dirname,'dist')
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    webpack具体配置

    下载Webpack

     npm install webpack webpack-cli --save-dev
    
    • 1

    启动Webpack

    npx webpack
    
    • 1
    npm i html-webpack-plugin  --save-dev
    
    • 1

    可以把打包生成文件放在内存里面,自动编译不用每次都输入启动命令

      npm i webpack-dev-server  --save-dev
    
    • 1

    使用npm run webpack-dev-server启动后,修改文件后会自动编译,不需要重复操作启动命令

    可以在package.json文件中,自定义启动命令
    每次就可以通过npm run buildnpm run webpack-dev-server启动项目

    "scripts": {
        "build": "webpack",
        "dev": "webpack-dev-server",
      },
    
    • 1
    • 2
    • 3
    • 4

    出口与入口

        entry: path.join(__dirname,'src','index.js'),
        output: {
    	    path: path.join(__dirname,'dist'),
    	    filename: 'bundle.js',
    	    publicPath:'CDS地址' //可以配置CDS地址
    	},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以配置多个入口文件,打包到不同js文件

     entry: {
        main: './src/a.js',
        sub: './src/b.js'
     },
     output: {
        path: path.join(__dirname,'dist'),
        filename: '[name].js'
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    loader

    loader 处理不同模块,不同类型文件
    没有options配置时,直接use:'loader名字',多个loader使用数组 use: ['style-loader','css-loader']
    options配置时use是一个对象
    loader:'xxxx' 只能使用一个loader,use可以使用多个

    use: {
       loader:'loader名字',
       options:{}
    }
    
    • 1
    • 2
    • 3
    • 4

    use执行顺序:从左到右(从小到上)

    处理js资源

    需要下载三个依赖

      npm i @babel/core @babel/preset-env babel-loader --save-dev
    
    • 1
    处理css资源

    css-loader将css资源编译成CommonJS的模块到js文件中
    style-loader将js中的css通过创建style标签添加到html文件中生效

    npm i style-loader css-loader -D
    
    • 1
    module: {
         rules: [
    		 {
    		   test:/.css$/,
    		     use: [
    		         'style-loader',//
    		         {
    			      loader:
    		          options: {
    	                modules: true,
    	              },
    		         }
    		         
    		     ]
    		 }
         ] 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    处理less资源
    npm i less less-loader -D
    
    • 1
    {
        test:/\.less$/,
        use: [
            'style-loader',
            'css-loader',
            'less-loader'
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    处理sass和scss资源
    npm i sass sass-loader  -D
    
    • 1
     {
        test: /\.sass$/,
        use: [
            'style-loader',
            'css-loader',
            'postcss-loader',
            'sass-loader'
        ],
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    处理Stylus资源
    npm i stylus stylus-loader  -D
    
    • 1
    {
        test:/\.styl$/,
        use: [
            'style-loader',
            'css-loader',
            'stylus-loader'
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    处理图片资源
    {
        test: /\.(jpg|png|gif)$/,
        type:"asset",
        parser: {
            dataUrlCondition:{
                // 小于10kb转base64
                maxSize: 10 * 1024
            },
            //输出路径
    	    generator: {
    	        filename:"static/images/[hash:10][ext][query]"  //hash值取前10位
        	}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    file-loader 打包图片

    [] 语法 占位符

      module: {
           rules: [
               {
                   test: /\.(jpg|png|gif)$/,
                   //use:'file-loader'
                   use: {
                       loader:'file-loader',
                       options:{
                           name:'[name]_[hash].[ext]'
                           outputPath:'images/'
                       }
                   }
               }
           ]
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    url-loader 打包图片

    转换成base64字符串
    好处:dist少了.jpg图片文件,减少了图片的HTTP请求
    坏处:图片过大加载完毕时间长
    使用需要图片只有1-2kb转为base64, 图片很大 file-loader 单独生成

      module: {
            rules: [
                {
                    test: /\.(jpg|png|gif)$/,
                    //use:'url-loader'
                    use: {
                        loader:'url-loader',
                        options:{
                            name:'[name]_[hash].[ext]'
                            outputPath:'images/'
                            limit:2048 //小于2M
                        }
                    }
                }
            ]
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    处理字体图标
    {
        test: /\.(ttf|woff2)$/,
        type:"asset/resource",
        generator: {
            filename:"static/icon/[hash][ext][query]"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    处理其他资源
    {
        test: /\.(ttf|woff2)|map3|map4|avi$/, // 在此处添加资源类型
        type:"asset/resource",
        generator: {
            filename:"static/icon/[hash][ext][query]"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    样式兼容postcss-loader

    兼容CSS样式,为css3样式添加前缀

      npm i postcss postcss-loader -D
    
    • 1
    module.exports = {
       Plugin:[
             require('autoprefixer')
         ]
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    npm i autoprefixer -D
    
    • 1

    package.json中配置

    "browerslist":[
         "> 1%", //市场份额大于1%的浏览器
         "last 2 version" //两个版本以上
     ],
    
    • 1
    • 2
    • 3
    • 4

    Plugins 插件

    HtmlWebpackPlugin 生成html

    CleanWebpackPlugin 删除dist重新打包

            template 模板
            plugins:[
                new HtmlWebpackPlugin({
                    template: path.join(__dirname,'src', 'index.html'),
                    filename: 'index.html'
                }),
                new CleanWebpackPlugin()
            ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Eslint 可组装的JavaScript和jsx检查工具

    配置文件很多种写法

    .eslintrc
    .eslinrc.js
    .eslinrc.json
    
    • 1
    • 2
    • 3

    ESlint会查找和自动读取它们,所以以上配置文件只需要一个即可
    package.jsoneslintConfig:不需要创建文件,在原有文件基础上写

    npm install eslint-webpack-plugin eslint --save-dev
    
    • 1
    CSS处理 mini-css-extract-plugin

    css目前被打包到js文件中,当js文件加载时,会创建一个style标签来生成样式
    这样对与网站来说,会出现闪屏现象,用户体验不好
    我们应该单独的css文件,通过link标签加载性能才好

    npm install mini-css-extract-plugin -D
    
    • 1
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    • 1
    use: [
       MiniCssExtractPlugin.loader,
       'css-loader',
       'postcss-loader',
       'sass-loader'
    ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    css压缩

    npm i css-minimizer-webpack-plugin -D
    
    • 1

    优化webpack

    1.提升开发体验

    css和js合并成一个文件,并且有很多其他代码,此时如果运行出错那么提示的代码位置我们是看不懂的。 一旦开发将开发代码文件很多,那么很难去发现出错在哪里。
    SourceMap(源代码映射)是一个用来生产代码与构建后代码一一映射的文件方案。
    它会生成一个xxx.map文件,里面包含源代码和构建代码每一行、每一列的映射的关系。当构建后代码出错了,会通过xxx.map文件,从构建后代码出错位置找到映射后源码出错位置,从而让浏览器提示源文件出错位置,帮助我们更快的找到错误根源。
    通过查看webpack.devtool文档可知,SourceMap的值有很多情况。实际开发只需要关注两种情况即可:
    1.开发模式 cheap-module-source-map
    优点:打包编译速度快,只包含映射
    缺点:没有映射列

    module.exports = {
        mode:'development',
        devtool:'cheap-module-source-map'
    }
    
    • 1
    • 2
    • 3
    • 4

    2.生产模式 source-map
    优点:包含行、列映射
    缺点:打包编译速度慢

    module.exports = {
        mode:'development',
        devtool:'source-map'
    }
    
    • 1
    • 2
    • 3
    • 4

    2.提升打包构建速度

    开发时我们修改一个模块代码,Webpack默认会将所有模块全部重新打包编译,速度很慢。
    所以我们需要做到修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模块不变,这样打包速度就能很快。

    HotModuleReplacement(HMR/热模块替换)

    在程序运行中,替换、添加或删除模块,而无需加载整个页面

    开发模式下

    module.exports = {
        devServer: {
            host:'localhost',
            port:'3000',
            open:true,
            hot:ftrue //开启HMR(默认值)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    js需要做到

    if(module.hot){
        //判断是否支持热模块替换功能
        module.hot.accept("./js/count") //count模块
    }
    
    • 1
    • 2
    • 3
    • 4

    实际项目中我们用到其它loader来实现vue-loaderreact-hot-loader

    oneOf

    每个文件只能在其中一个loader配置处理

    rules:[
        {
            //每个文件只能在其中一个loader配置处理
            oneOf:[]
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    include/exclude

    include只处理某些文件
    exclude排除,除了某些文件以为其它文件都能处理
    一般情况选择其中一个就可以了

    {
        test: /\.js$/,
         loader:'babel-loader',
         include: path.join(__dirname,'src'),
         exclude: /node_modules/
     },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Cache

    打包时js文件都要经过Eslint检查和Babel编译 ,速度比较慢
    我们可以缓存之前的Eslint检查 和Babel编译结果,这样第二次打包时速度就会更快

    对Eslint检查 和Babel编译结果进行缓存

    {
        test: /\.js$/,
        loader:'babel-loader',
        exclude: /node_modules/,
        options: {
            cacheDirectory:true,//开启babel缓存
            cacheCompression:true//关闭缓存压缩
    
       }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Thead

    当项目越来越庞大时,打包速度越来越慢,甚至需要一个下午才能打包出来代码,这个速度比较慢的
    我们想要继续提升打包速度,其实就是要提升js的打包速度,因为其他文件比较少
    而对js文件处理主要是eslint、babel、Terser三个工具,所以我们要提升他们的速度
    我们可以开启多进程同时处理js文件,这样速度就比之前的进程打包更快

    多进程打包:开启电脑的多个进程同时干一件事,速度更快
    需要注意:请仅在特别耗时到操作中使用,因为每个进程启动就有大约600ms左右的开销

    我们启动进程的数量就是吗CPU的核数
    1.如何获取CPU的核数,因为每个电脑不一样

    cosnt os = require('os')
    const threads = os.cpus().length;
    
    • 1
    • 2
    npm i thread-loader -D
    
    • 1
    {
        test: /\.js$/,
        include: path.join(__dirname,'src'),
        use:[
            loader:'babel-loader',
            options:{
                works: threads,
            }
        ]
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
     new ESLintWebpackPlugin({
        context: path.resolve(__dirname, './src'),
        exclude: 'node_modules',//默认值
        threads //开启多进程和设置进程数量
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    压缩js,内置的不用下载

    const TerSerWebpackPlugin = require('terser-webpack-plugin')
    
    • 1
    new TerSerWebpackPlugin({
        parallel:threads //开启多进程和设置进程数量
    })
    
    • 1
    • 2
    • 3

    3.减少代码体积

    Tree Shaking

    Tree Shaking是一个术语,通常用于描述移除JavaScript中没有用上的代码。
    没有处理的话我们打包时会引入整个库,但实际上可能我们只用上极小部分功能,这样整个库打包体积就太大了

    注意:它依赖 ES Module
    
    • 1

    Webpack 默认开启了这个功能

    babel

    为编译的每个文件都插入了辅助代码,使代码体积过大
    Babel 对一些公共方法使用了非常小的辅助代码,比如 _extend,默认情况下会被添加到每一个需要他的文件中
    可以将这些辅助代码作为一个独立模块,来避免引入
    禁用了Babel自动对每个文件的runtime注入,而是引入并且使用所有辅助代码从这里引用

    npm i @babel/plugin-transform-runtime -D
    
    • 1

    {

        test: /\.js$/,
        loader:'babel-loader',
        include: path.join(__dirname,'src'),
        plugin:[' @babel/plugin-transform-runtime']
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    图片压缩
    npm i image-minimizer-webpack-plugin imagemin -dataUrlCondition
    
    • 1

    无损压缩

    npm install imagemin-gifsicle imagemin-jpegtran imagemin-svgo -D
    
    • 1

    有损压缩

    npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D
    
    • 1
    code Split

    js会打包到一个文件,体积太大
    分割文件,生成多个js文件
    按需加载 需要哪个文件就加载哪个文件

     entry: {
        main: './src/a.js',
        sub: './src/b.js'
     },
     output: {
        path: path.join(__dirname,'dist'),
        filename: '[name].js'
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.优化代码运行性能

    未完待更新

  • 相关阅读:
    索引构建磁盘IO太高,巧用tmpfs让内存来帮忙
    苹果Audio Classifier使用问题
    基于springboot+vue的旅游管理系统
    使用逻辑分析仪处理IIC信号
    pandas使用dropna函数删除dataframe数据中多个数据列的内容至少包含一个缺失值的数据行(使用subset参数指定多个数据列)
    在鲲鹏服务器搭建k8s高可用集群分享
    多线程系列(十五) -常用并发工具类详解
    基于JavaSwing开发图书销售管理系统 课程设计 大作业 毕业设计
    汽车空调器前缸盖数控加工工艺的制订及夹具设计
    思科设备EIGRP配置命令
  • 原文地址:https://blog.csdn.net/qq_38367703/article/details/126880412