学习webpack中的核心概念

838 阅读2分钟

2020.12.09更新

项目遇到一个问题,还没找到解决方案,先记录下: 直接本地输入基础路径可以进入,但一刷新页面空白,怀疑是路径配置不对,资源没有加载成功。

publicPath

  • webpack.config中,output项的publicPathc:影响资源生成路径。
该配置能帮助你为项目中的所有资源指定一个基础路径,它被称为公共路径(publicPath)。

这里说的所有资源的基础路径是指项目中引用css,js,img等资源时的基础路径,这个基础路径要配合具体资源中指定的路径使用,有如下公式:

静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径
output.publicPath = '/dist/'  // 注意:要写出/publicPath/

// image
options: {
 	name: 'img/[name].[ext]?[hash]'
}

// 最终图片的访问路径为
output.publicPath + 'img/[name].[ext]?[hash]' = '/dist/img/[name].[ext]?[hash]'
  • devServer中的publicPath:影响资源在本地开发环境(浏览器)中的访问,换句话说,这里设置的是打包后资源存放的位置。 如果在本地开发环境中配置了output的publicPath,那么在devServer中也要做相应的配置。

1、webpack的作用

  • 是一个现代 JavaScript 应用程序的 静态模块打包工具
  • 能够构建项目的依赖图,反应出项目中所需的各个模块,生成一个或多个bundle。

2、entry

entry指明用哪个文件来作为依赖图的起点,然后webpack找到enrty依赖了哪些模块和库。webpack从这里开始转发。

module.exports = {
    // 单入口
    entry:'src/index.js' 
    
    //多入口,数组形式
    [
     isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'), //isEnvDevelopment = webpackEnv === 'development';
     paths.appIndexJs //appIndexJs: resolveModule(resolveApp, 'src/index'),
    ].filter(Boolean)
}

3、output

指明将webpack打包生成的bundle输出到哪里,以及这些bundle的命名规则。

module.exports = {
    output:{
        path:'build' //bundle输出到何处
        filename:'[name].bundle.js' //entry中的文件生成的bundle的名称
        chunkFilename:'[name].[contenthash:8].chunk.js' //非入口(non-entry) chunk 文件的名称。
        }
}

4、loader

  • webpack 只能理解 JavaScript 和 JSON 文件。
  • loader的作用是将其他类型的文件转化为有效的模块。
  • module.rules 允许用户在 webpack 配置中指定多个 loader。
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          },
          { loader: 'sass-loader' } //执行顺序sass-loader ->css-loader ->style-loader
        ]
      }
    ]
  }
};

5、plugin

插件可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。可以用来处理各种各样的任务。

//使用一个plugin
//1、需要 require()改插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件

module.exports = {
  plugins: [
  //2、多次使用的插件,通过使用 new 来创建它的一个实例。
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

6、mode

设置相应环境以执行相应的优化(optimization),默认为production

module.exports = {
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
 }

7、bail

在遇到第一个错误时,webpack是否停止打包。

module.exports = {
  bail: true //退出其打包过程
};

8、devtool

指明webpack是否,及如何生成source map。

module.exports = {
//source-map 原始源代码
//cheap-module-source-map 原始源代码(仅限行)
    devtool: isEnvProduction ? 'source-map' : 'cheap-module-source-map'
      }

9、optimization

module.exports = {
  //...
  optimization: {
    //是否使用 TerserPlugin 压缩true bundle。mode为production时默认为true
    minimize: false,
    //使用定制 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
    minimizer: [
        new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true, // Must be set to true if using source-maps in production
            terserOptions: {
              // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
            }
      }),
    ],
    // 打包优化策略(待深入学习)
     splitChunks: {
      // include all types of chunks
      chunks: 'all' 
    },
    // 用于优化缓存(待深入学习)
     runtimeChunk: true
  }
};

10、resolve

设置模块如何被解析

module.exports = {
  resolve: {
    //设置别名
    alias: {
        'react-native': 'react-native-web',
        '~': path.resolve(__dirname, '../src/'),
        '@locale': '@enos/dpl/lib/locale/localeUtils'
      },
    //自动解析扩展名,引入文件时就不需要加上扩展名了
    extensions: ['.wasm', '.mjs', '.js', '.json'], //如引入file.js,只需要import File from '../path/to/file';
    //在哪些目录下解析模块
    modules: ['node_modules'],
    //额外使用的插件
    plugins: [
        new DirectoryNamedWebpackPlugin()
    ]
  }
};

11、resolveLoader

仅用于解析 webpack 的 loader 包

12、module

配置项目中不同类型和功能的模块

module.exports = {
  module: {
    rules: [
      {parser: {requireEnsure: false}}, //解析器
      {
        enforce: 'pre', //前置loader
        exclude: /node_modules\/(?!(ansi-styles)\/).*/, //排除哪些文件
        include: paths.appSrc, //包括哪些文件
        loader: require.resolve('url-loader'), //废弃,支持use替代
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
        ],
      },
      {
        test: /\.css$/,
        oneOf: [
          //当规则匹配时,只使用第一个匹配规则。
          {
            resourceQuery: /inline/, // foo.css?inline
            use: 'url-loader',
          },
          {
            resourceQuery: /external/, // foo.css?external
            use: 'file-loader',
          },
        ],
      },
    ],
  },
};

13、node

这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量和模块。

module.exports = {
  node: {
    dns: 'mock',
    fs: 'empty',
    path: true,
    url: false
  }
};

14、performance

性能配置

module.exports = {
  performance: {
    hints: false, //false | "error" | "warning" 文件过大时如何报错
  }
};

更多配置参考:

webpack.docschina.org/configurati…