• webpack4常用片段


    webpack 4常用

    初始化

    npm init
    // Webpack 4.0以后需要单独安装
    npm install webpack webpack-cli --save-dev

    基础的config

    entry: './src/index.js',
    mode: 'development',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    }

    字段说明

    • entry : 入口文件。一般是一个string,多个可以使用数组或者json
    entry:"a.js";
    entry:["a.js","b.js"];
    entry:{
        index:["a.js"],
        index2:["b.js"]
    }
    • output : 出口文件 json 
    output : {
        fileName:"a.js",
        path:path.resolve(__dirname,"dist");
    }
    • mode 提供 mode 配置选项
    mode : production;
    mode : development;
    • loader 用于对模块的源代码进行转换
    module:{
        rules:[
            {
                test:/.css$/,
                use:[
                    {
                        loader:"style-loader"
                    },
                    {
                    loader: 'css-loader',
                    options: {
                      modules: true
                    }
                  }
                ]
            }
        ]
    }
    • plugin 插件目的在于解决 loader 无法实现的其他事。
    plugin : [
        new webpack.optimize.UglifyJsPlugin(),
        new HtmlWebpackPlugin({template: './src/index.html'})
    ]
    webpack常用

    module.noParse

    防止 webpack 解析那些符合匹配条件的文件,忽略的文件夹中不应该含有 import、require、define的调用,或任何其他导入机制,忽略的 library 可以提高构建效率。

    开启sourceMap

    css在cssloader的option设置{sourceMap:true},js在 devtool: 'inline-source-map'

    module.exports = {
        entry:"./index.js",
        output:{
            filename:"[name].js"
        },
        module:{
            rules:[
                {
                    test:/.(sc|c|sa)ss$/,
                    use:[
                        {
                            loader:"css-loader",
                            options:{
                                sourceMap: true
                            }
                        }
                    ]
                }
            ]
        },
        devtool:"source-map"
    }

    devtool可选值

    1. source-map
    2. inline-source-map
    3. inline-cheap-source-map
    4. inline-cheap-module-source-map
    5. eval

    热更新(webpack.HotModuleReplacementPlugin)

    const webpack = require('webpack');
    module.exports = {
        devServer: {
          contentBase: path.join(__dirname, 'dist'), //本地服务器所加载的页面所在的目录
            clinetLogLevel: 'warning', // 可能值有 none, error, warning 或者 info (默认值)
            hot:true,//启动热更新替换特性,需要配合 webpack.HotModuleReplacementPlugin 插件
            host:'0.0.0.0', // 启动服务器的 host
            port:7000,      // 端口号
            compress:true,  // 为所有服务启用gzip压缩
            overlay: true,  // 在浏览器中显示全屏覆盖
            stats: "errors-only" ,// 只显示包中的错误
            open:true, // 启用“打开”后,dev服务器将打开浏览器。
            proxy: {   // 设置代理
                "/api": {
                    target: "http://localhost:3000",
                    pathRewrite: {"^/api" : ""}
                }
            }
       },
       plugins::[
            new webpack.NamedModulesPlugin(),
            new webpack.HotModuleReplacementPlugin()
       ]
    }
    
    // package.json
    {
        .....
        script:{
            "dev":"webpack-dev-server --config webpack.dev.js"
        }
        .....
    }

    别名替换(resolve.alias)

    给定对象的键后的末尾添加 $,以表示精准匹配

    module.exports = {
        resolve:{
            alias:{
                '@src':path.resolve(__dirname, 'src/')
            }
        }
    
    }

    resolve 可配置参数:

    aliasFields 

    enforceExtension如果设置为true则不许可引入无扩展名的文件 例如 false可以使用require("./index") true 则必须require("./index.js");

    extensions 自动解析确定扩展名 默认值为 [".js",".json"],在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试访问文件是否存在。

    css单独打包(mini-css-extract-plugin)

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module: {
      rules: [
        {
          test: /.(sc|c|sa)ss$/,
          use: [
            MiniCssExtractPlugin.loader, 
            {
              loader:"css-loader",
              options:{ sourceMap: true }
            },      ]
        }
      ]
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css', // 最终输出的文件名
        chunkFilename: '[id].css'
      })
    ]

    压缩js和css(uglifyjs-webpack-plugin、optimize-css-assets-webpack-plugin)

    const UglifyJsPlugin = require('uglifyjs-webpack-plugin');//压缩js
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');//压缩css
    module.exports = {
      // ... 省略
      plugins: [
        // ... 省略
        new OptimizeCssAssetsPlugin({}),
        new UglifyJsPlugin({
            //当 JS 没有发生变化则不压缩
          cache: true, 
          //是否启用并行压缩;
          parallel: true,
           sourceMap: true
        })
      ],
    }
    引入动态文件、处理html(hash)(HtmlWebpackPlugin)
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    plugins: [
      new HtmlWebpackPlugin({
        title: "title!",   // 生成的文件标题
        filename: "main.html", // 最终生成的文件名
        minify: { // 压缩选项
          collapseWhitespace: true, // 移除空格
          removeComments: true, // 移除注释
          removeAttributeQuotes: true, // 移除双引号
        }
      })
    ],

    清理目录(clean-webpack-plugin)

    const {CleanWebpackPlugin} = require('clean-webpack-plugin');
    plugins: [
      new CleanWebpackPlugin()
    ],
    图片处理和优化(file-loader(处理)、image-webpack-loader(优化))
    module: {
      {
        test: /.(png|svg|jpg|jpeg|gif)$/,
        include: [path.resolve(__dirname, 'src/')],
        use: ["file-loader",{
            loader: "image-webpack-loader",
            options: {
              mozjpeg: { progressive: true, quality: 65 },
              optipng: { enabled: false },
              pngquant: { quality: '65-90', speed: 4 },
              gifsicle: { interlaced: false },
              webp: { quality: 75 }
            }
          },
        ]
      }]
    },

    图片 base64 处理(url-loader 不能和image-webpack-loader一起使用)

    module: {
      {
        test: /.(png|svg|jpg|jpeg|gif)$/,
        include: [path.resolve(__dirname, 'src/')],
        use: [
          {
            loader: 'url-loader', // 根据图片大小,把图片转换成 base64
              options: { limit: 10000 }, 
          },
        ]
      }]
    },

    字体处理(file loader)

    module: {
      {
        test: /.(woff|woff2|eot|ttf|otf)$/,
        include: [path.resolve(__dirname, 'src/')],
        use: [ 'file-loader' ]
      }
    },
    配置合并和提取公共配置(webpack-merge)
    const merge = require('webpack-merge');
    const common = require('./webpack.common.js');
    let devConfig = {
    // configs...
    }
    module.exports = merge(common, devConfig)
    

      

    设置代理

      devServer: {
        // ... 省略其他
        proxy: { 
          "/api": { // 以 '/api' 开头的请求,会跳转到下面的 target 配置
            target: "http://192.168.30.33:8080",
            pathRewrite: {
              "^api": "/mock/api"
            }
        }
     }

    配置外部拓展(externals)

    当我们使用 CDN 引入 jquery 时,我们并不想把它也打包到项目中,我们就可以配置 externals 外部拓展的选项,来将这些不需要打包的模块从输出的 bundle 中排除:<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>配置 externals:module.exports = { // ... 省略其他 externals: { jquery: 'jQuery' }, }

    打包分析报表及优化总结(webpack-bundle-analyzer)

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    module.exports = {
      plugins: [
        new BundleAnalyzerPlugin()
      ]
    }

    分割代码(SplitChunksPlugin)(针对复用的体积大于30k)

    {
    
    optimization.splitchunks参数:{
        minSize 分离后的最小块文件大小,单位为字节
        minChunks 分离前,该块被引入的次数(也就是某个js文件通过import或require引入的次数)
        maxInitialRequests 一个入口文件可以并行加载的最大文件数量
        maxAsyncRequests 内层文件(第二层)按需加载时最大的并行加载数量
        name 用以控制分离后代码块的命名,当存在匹配的缓存组(后面会说到)时,命名使用缓存组中的name值,若不存在则为  [来源]~[入口的key值].js  的格式
        automaticNameDelimiter 修改上面的 “~” ,  若改为: “-” 则分离后的js默认命名规则为 [来源]-[入口的key值].js 
        test 用于规定缓存组匹配的文件位置,test: /node_modules/  即为匹配相应文件夹下的模块
        cacheGroups 名字叫做缓存组,其实就是存放分离代码块的规则的对象,叫做cacheGroup的原因是webpack会将规则放置在cache流中,为对应的块文件匹配对应的流,从而生成分离后的块。
        chunks 匹配的块的类型:initial(初始块),async(按需加载的异步块),all(所有块)
    }
    }
    
    optimization: {
            runtimeChunk: {
                "name": "manifest"
            },
            splitChunks: {
                chunks: 'all',
                cacheGroups: {
                    common: {
                        minChunks: 2,
                        name: 'commons',
                        chunks: 'async',
                        priority: 10,
                        reuseExistingChunk: true,
                        enforce: true
                    }
                }
            }
        }

    打包一个可以被import的js

    output: {
      library: "myDemo",//如果在 HTML 页面中使用script标签引入打包结果文件,那么变量myDemo对应的值将会是入口文件(entry file)的返回值。
      libraryTarget: "commonjs2"
     }

    libraryTarget:

    • "var" - 以直接变量输出(默认library方式) var Library = xxx (default)

    • "this" - 通过设置this的属性输出 this["Library"] = xxx

    • "commonjs" - 通过设置exports的属性输出 exports["Library"] = xxx

    • "commonjs2" - 通过设置module.exports的属性输出 module.exports = xxx

    • "amd" - 以amd方式输出

    • "umd" - 结合commonjs2/amd/root

    全局引入包(ProvidePlugin)

    plugins: [
        //提供全局的变量,在模块中使用无需用require,import引入
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: 'jquery'
        }),
      ]

    全局常量(DefinePlugin)

    plugins: [
        new webpack.DefinePlugin({
         'url':'www.baidu.com'
        }),
     ]

    copy文件(copy-webpack-plugin)

    npm install --save-dev copy-webpack-plugin
    const CopyWebpackPlugin = require('copy-webpack-plugin');
     new CopyWebpackPlugin([
       {
         from:__dirname+'/public/lib',
         to:__dirname+'/build/lib'
       }
     ])

    优化模块查找路径 resolve.modules

    Webpack的resolve.modules配置模块库(即 nodemodules)所在的位置,在 js 里出现 import 'vue' 这样不是相对、也不是绝对路径的写法时,会去 nodemodules 目录下找。但是默认的配置,会采用向上递归搜索的方式去寻找,但通常项目目录里只有一个 nodemodules,且是在项目根目录,为了减少搜索范围,可以直接写明 nodemodules 的全路径

    const path = require('path');
    
    function resolve(dir) { // 转换为绝对路径
       return path.join(__dirname, dir);
    }
    
    resolve: {
        modules: [ // 优化模块查找路径
            path.resolve('src'),
            path.resolve('node_modules') // 指定node_modules所在位置 当你import 第三方模块时 直接从这个路径下搜索寻找
        ]
    }

    配置好src目录所在位置后,由于util目录是在src里面 所以可以用下面方式引入util中的工具函数// main.js import dep1 from 'util/dep1'; import add from 'util/add';

    多线程打包(较小项目不建议,反而会慢)

    const HappyPack = require('happypack');
    const os = require('os'); // node 提供的系统操作模块
    
     // 根据我的系统的内核数量 指定线程池个数 也可以其他数量
    const happyThreadPool = HappyPack.ThreadPool({size: os.cpus().lenght})
    
    module: {
        rules: [
           {
               test: /.js$/,
               use: 'happypack/loader?id=babel',
               exclude: /node_modules/,
               include: path.resolve(__dirname, 'src')
           }
        ]
    },
    plugins: [
        new HappyPack({ // 基础参数设置
            id: 'babel', // 上面loader?后面指定的id
            loaders: ['babel-loader?cacheDirectory'], // 实际匹配处理的loader
            threadPool: happyThreadPool,
            verbose: true
        }),
        new Happypack({其他loader配置})
    ]
  • 相关阅读:
    Clean Code读书笔记
    Junit 断言 assertThat Hamcrest匹配器
    SpringMVC 常用注解
    SpringMVC 流程 配置 接口
    ng-select ng-options ng-repeat的用法与区别
    javascript总结
    intellij安装 配置 创建项目
    git常用操作指令
    springmvc报错 org.springframework.web.servlet.DispatcherServlet
    linux笔记:RPM软件包管理-源码包管理
  • 原文地址:https://www.cnblogs.com/jinzhenzong/p/12001163.html
Copyright © 2020-2023  润新知