zoukankan      html  css  js  c++  java
  • webpack常见配置信息

    1. devtool代码调试

    1. 生产模式下

    source-map: 生成一个map文件,直接定位到源码的行列

    ✅可以使用该模式,用于测试服务器

    cheap-source-map: 只能定位到行,且只能定位到babel转码后的代码

    cheap-module-source-map: 只能定位到行,但是可以定位到源码

    2. 开发模式下

    eval: 定位到编译后的代码

    cheap-eval-source-map:  定位到babel转码后的行

    cheap-module-eval-source-map: 定位到源码的行

    eval-source-map: 定位到源码的行列

    ✅推荐使用该方法

    line-*模式慢,不考虑

    2. 第三方库的应用

    1. webpack.ProvidePlugin

    对于类似lodash的各模块频繁使用的情况, 为了避免每次都手动引入,可以使用该插件实现全部模块的自动引入该文件。只是优化了重复引入的问题,打包体积和直接引入相同。

        new webpack.ProvidePlugin({
          _: 'lodash'
        }),

    相当于在每个模块都默认执行了引入,用户可以直接使用。

    import _ from 'lodash';

    ❎该方法不是全局变量

    2. expose-loader

    该方法可以避免重复引入高频使用的库。而且可以将其作为全局变量。对于debugging很方便。 在控制台就可以直接使用。

    在入口文件使用:

    // 必须是require
    require('expose-loader?_!lodash');
    // !前是全局变量名称;!后是库名

    然后可以直接使用window._访问。

    3. externals

    当已经从CDN等外部引入第三方库时,如果代码中又手动引入了同样的库,该配置可以让webpack不打包配置中的第三方库。

     externals: {
        lodash: '_' // :前的key是库的名称;后面是全局变量的名称
      }

    想要起作用,必须要在html中引入CDN

    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

    如上,即使在模块中手动引入,webpack也不会将其打入包内

    import _ from 'lodash'; //会忽略引入的lodash库
    
    const a = _.join(['a', 'b'], '~'); 

    4. html-webpack-externals-plugin

    3中,需要在html文件中引入CDN文件。如果不想手动引入,直接配置生成,可以使用该插件。

    ⚠️该插件必须在html-webpack-plugin插件实例化之后再进行实例化

    new HtmlWebpackPlugin({
    }),
    new HtmlWebpackExternalsPlugin({
      externals: [
        {
          module: 'lodash',
          global: '_',
          entry: 'https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js'
        }
      ]
    }),

    3. 打包后的代码添加注释说明

    new webpack.BannerPlugin('Lyra'),

    4. 拷贝静态文件(txt/doc等)

        new CopyWebpackPlugin([{
          from: path.join(__dirname, './src/assets'),
          to: path.join(__dirname, './dist/assets')
        }]),

    5. devServer实现proxy代理,和模拟服务器

    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        port: 8080,
       host: 'localhost',
    compress: true, // 启用gzip压缩 before(app) {
    // devServer本身是一个express服务器,app是其对应的app;before指的是在app.listen之前执行 app.get('/api/user', (req, res) => { res.json([{ a: 'lyra' }]); }); }, proxy: { '/api': { target: 'http://localhost3000', // 代理本地服务到目标服务器;相当于nginx,不存在跨域问题 pathRewrite: { '^/api': '' // 重写路径;如:/api/user -> /user } } } },

    6. webpack-dev-middleware模拟实现webpack-dev-server

    const express = require('express');
    const WebpackDevMiddleware = require('webpack-dev-middleware');
    const webpack = require('webpack');
    const webpackConfig = require('./webpack.config.js');
    
    
    const app = express();
    // 返回一个编译对象
    const compiler = webpack(webpackConfig);
    // 1.使用webpack-dev-middleware插件启动编译
    // 2.使用该插件响应客户端请求的打包文件
    app.use(WebpackDevMiddleware(compiler, {}));
    
    app.get('/api/user', (req, res) => {
      res.json([{ a: 'name' }]);
    });
    
    app.listen(5000);

    通过命令启动

      "scripts": {
        "node": "node devServer.js",
        "build": "webpack",
        "dev": "webpack-dev-server --open"
      },

    7. 模块解析规则resolve

    1. extensions

    当引入文件不写扩展名时,根据extentsions设置的规则,进行文件查找。

    module.exports = {
      ...
      resolve: {
         extensions: ['.js', '.jsx', '.json']
      }  
    }

    2. alias

    给查找路径定义别名,加快文件查找速度。

    对于引入npm安装的模块时,它会按照查找规则,依次查找。对于相对路径查找,也会按照相对路径的规则,依次查找。

    通过定义alias可以直接按照alias指定的路径查找,避免路径解析消耗的时间。

    module.exports = {
      //...
      resolve: {
        alias: {
          Utilities: path.resolve(__dirname, 'src/utilities/'),
          Templates: path.resolve(__dirname, 'src/templates/')
        }
      }
    };

    引入alias之前:

    import Utility from '../../utilities/utility';

    引入之后

    import Utility from 'Utilities/utility';

    另外,别名最后加上$表示,严格匹配,即使用时只能是别名,其他的都不匹配。

    module.exports = {
      //...
      resolve: {
        alias: {
          xyz$: path.resolve(__dirname, 'path/to/file.js')
        }
      }
    };

    示例:

    import Test1 from 'xyz'; // 严格匹配,按照别名解析
    import Test2 from 'xyz/file.js'; // 不严格匹配,按照原来的解析规则解析

    3. modules

    指定查找的模块,也可以在默认规则上添加其他需要查找的模块

    module.exports = {
      //...
      resolve: {
        modules: ['node_modules', 'myloaders'] //后者是自定义的模块
      }
    };

    4. mainFields

    定义入口文件字段的查找顺序

    module.exports = {
      //...
      resolve: { //定义了先查找package.json中的browser字段...
        mainFields: ['browser', 'module', 'main']
      }
    };

    5. mainFiles

    当解析文件夹目录的时候,会按照该字段查找文件夹中的文件

    module.exports = {
      //...
      resolve: {
        mainFiles: ['index'] //也可以修改为main.js等
      }
    };

    8.resolveLoaders

    属性和规则同resolve, 对应的是处理模块的loader的查找规则。

    module.exports = {
      //...
      resolveLoader: {
        modules: ['node_modules'],
        extensions: ['.js', '.json'],
        mainFields: ['loader', 'main']
      }
    };

    在module中按照rules使用loaders进行解析时,查找loader模块默认按照resolveLoader中的定义规则查找。

    9. 自定义全局变量webpack.DefinePlugin

    该插件中对应的字符串的内容,会被当作代码片段解析。变量对应的值如果是非字符串,要通过JSON.stringify()进行序列化。

        new webpack.DefinePlugin({
          "PRODUCTION": JSON.stringify(true),
          "AUTHOR": {
            "USER": JSON.stringify('lyra') // 字符串也需要序列化,否则按照表达式处理
          }
        }),

    10. 环境变量process.env.NODE_ENV

    在代码中可以通过访问process.env.NODE_ENV来获取当前项目的mode值。

    应用:

    可以根据该值来封装函数,实现在不同环境下的不同表现。

    const oldLog = console.log;
    // 覆盖原来的日志函数
    console.log = function newlog() {
      if (process.env.NODE_ENV === 'development') {
        oldLog('开发环境打印日志');
      }
    };
    
    //使用时,引入该文件
    import './console';
    
    console.log("node_env", process.env.NODE_ENV);

    11. glob匹配多入口文件

    glob是一个匹配文件的工具。

    npm i glob

    如果需要实现多个入口文件,使用多个html模版文件。我们可以将入口文件统一放入entries文件中;将模版文件统一放入templates文件夹中。且名称一一对应。

    则不在需要一个个添加html-webpack-plugin插件。可以批量操作。

    const glob = require('glob');
    
    const files = glob.sync('./src/entries/*.js'); //获取匹配的所有文件路径
    const entries = {};
    const templates = [];
    files.forEach((file) => {
      const fileName = path.basename(file, '.js'); //获取文件的名称,不含扩展名
      entries[fileName] = file;
      templates.push(new HtmlWebpackPlugin({
        template: `./src/templates/${fileName}.html`,
        filename: `${fileName}.html`,
        // hash: true,
        chunks: [fileName], // 指定各自的chunk块,否则所有chunk将都引入
        chunksSortMode: 'manual'
      }));
    });

    12. 日志优化stats

    webpack编译时打印的日志多数是无效日志,我们通过设置stats的值自定义显示的代码。

    stats默认是"normal"。

    module.exports = {
      //...
      stats: 'normal'
    };

    还可以是其他值,如

    1. errors-only        //只打印错误信息
    2. errors-warnings // 错误和警告
    3. verbose            // 打印所有的信息
    4. minimal            // 只打印错误和新的编译
    5. none                // 不打印

    如果想要更清晰,可以使用friendly-errors-webpack-plugin插件(作用不大)。

    module.exports = {
      // ...
      plugins: [
        new FriendlyErrorsWebpackPlugin(),
      ],
    }

    13. 实现ES6等新API的兼容问题polyfill

    一般会推荐使用babel-polyfill,用法

    import 'babel-polyfill';

    但是该方法会增大打包文件的体积,而且对于不需要的浏览器也会打包。

    为了解决这些问题,可以使用

    <script src="https://polyfill.io/v3/polyfill.min.js/"></script>

    该接口可以根据UserAgent返回需要的polyfills。如果是Chrome浏览器,将返回空内容,因为它不需要polyfills。

    13. stats.json

    npx webpack --profile --json > stats.json

    通过名称生成stats.json文件,里面包含打包的所有信息。主要有几个属性:

    1. chunks

    代码块。生成代码的途径:

    1. 入口文件会生成对应的chunk

    output: {
        filename: '[name].[contenthash].js'  //hot:true下不能contenthash
    }

    2. 动态导入模块会生成对应的chunk(import())

    这类代码块的chunk命名规则如下
    import(/* webpackChunkName: "example" */'./example')

    3. splitChunk会生成分割的代码chunk(代码块)

    optimization: {
      splitChunks: {
        cacheGroups: {
          vendors: {
            chunks: 'initial', //必须有,默认是async(import());initial是同步,不设置该值不会生成代码块
            name: 'vendors', //设置代码块名称
            test: /node_modules/, //指定要打包的模块
            minSize: 50*1024,  // 打包最小体积
            priority: 1
          }, 
          commons: {
            chunks: 'initial',
            name: 'commons',
            test: /src/,
            minChunks: 2, // 至少被minChunks个module引用过
            priority: 2
          }
        }
      }
    }, 

    2. modules

    在webpack中一切皆模块。每个js,css,image等都是模块。

    webpack本身只能识别js文件,对于任何非js文件都需要通过loader进行编译, 最终将其编译为js输出。

    3. assets

    最后打包生成的所有文件都是assets。

     

  • 相关阅读:
    C++分数类
    2019 SDN大作业
    个人作业-软工实践总结
    2019 SDN上机第7次作业
    2019 SDN上机第6次作业
    2019 SDN课程阅读作业(2)
    个人作业--软件评测
    2019 SDN上机第5次作业
    2019 SDN上机第4次作业
    2019 SDN第一次阅读作业
  • 原文地址:https://www.cnblogs.com/lyraLee/p/12042140.html
Copyright © 2011-2022 走看看