深入解析webpack的五个核心概念

javascriptjavascript 2023-08-29 02:29:10 840
摘要: webpack是一种前端资源构建工具,一个静态模块打包器(modulebundler);webpack有5大核心概念(入口、输出、loader、插件、模式),下面本篇文章就来带大家深入了解一下,希望对大家有所帮助!webpack五个核心概念1.Entry入口(En...

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler);webpack有5大核心概念(入口、输出、loader、插件、模式) ,下面本篇文章就来带大家深入了解一下,希望对大家有所帮助!

webpack 五个核心概念

1. Entry

入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。

2. Output

输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。

3. Loader

webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。

4. Plugins

插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。

5. Mode

模式(Mode)指示 webpack 使用相应模式的配置。

下面就来给大家详细介绍一下webpack这五个核心概念。

1、入口(Entry)

entry 对象是用于 webpack 查找启动并构建 bundle。entry 是应用程序的起点入口,从这个起点开始,应用程序启动执行。如果传递一个数组,那么数组的每一项都会执行。入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

简单规则:每个 HTML 页面都有一个入口起点。单页应用(SPA):一个入口起点,多页应用(MPA):多个入口起点。

默认值是 ./src/index.js,但你可以通过在 webpack configuration 中配置 entry 属性,来指定一个(或多个)不同的入口起点。例如:

//单入口--字符串
module.exports = {
  entry: './path/to/my/entry/file.js',
};
//多入口--数组
module.exports = {
  entry: ['./src/index.js', './src/add.js']
};
//多入口--对象
module.exports = {
  entry: {
    home: './home.js',
    about: './about.js',
    contact: './contact.js'
  }
};

entry的值类型:

  • 字符串:单入口,打包形成一个chunk,最终只会输出一个bundle文件,chunk 的名称默认是 main

  • 数组:多入口,所有的入口文件最终也只会形成一个chunk,最终输出一个 bundle 文件,chunk 的名称默认为 main。一般只用在 HMR 功能中让html热更新生效

  • 对象:多入口,有多少个 key 就会形成多少个chunk,也就输出多少个 bundle 文件,每个键(key)会是 chunk 的名称。在对象类型中,每个key的值还可以是一个数组,不仅仅是一个字符串

2、输出(output)

output 指示 webpack 如何去输出、以及在哪里输出你的bundle、asset 和其他你所打包或使用 webpack 载入的任何内容。输出的 bundle 的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。

你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

//webpack.config.js
const path = require('path');
module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
};

我们可以通过 output.filenameoutput.path 属性,来告诉 webpack bundle 的名称,以及 bundle 生成到哪里。

2.1、output.filename(文件名和目录)

此选项决定了每个输出 bundle 的目录和名称。这些 bundle 将写入到 output.path 选项指定的目录下。

对于单个入口起点,filename 会是一个静态名称。然而,当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用其他方法来让每个 bundle 都有一个唯一的名称。

//单入口时:
module.exports = {
  //...
  output: {
    filename: 'js/bundle.js'
  }
};
//多入口--使用入口名称:
module.exports = {
  //...
  output: {
    filename: '[name].bundle.js'
  }
};
//多入口--使用每次构建过程中,唯一的 hash 生成
module.exports = {
  //...
  output: {
    filename: '[name].[hash].bundle.js'
  }
};
...

2.2、output.path(文件目录)

output.path 指定所有输出文件的目录,即将来所有资源输出的公共目录。path 必须是绝对路径。

module.exports = {
  //...
  output: {
    path: path.resolve(__dirname, 'dist/assets')
  }
};

2.3、output.publicPath(引用资源的路径前缀)

publicPath 指定的是 html 文件中的所有资源引入的公共路径前缀。它并不会对生成文件的路径造成影响,而是在 html 文件引入各种资源时,将 publicPath 作为前缀加到引入资源的路径前面。

实例:

在 vue-cli 生成的 webpack 配置中,生产环境下 publicPath 的值默认是 '/',即当前目录的根目录。

打包过后,我们打开 html 文件,可以看到 html 文件中引入的资源路径为:

可以看到,都在路径前面加了 / 符号。当我们打开浏览器访问生成的 html 文件时,会发现报错,资源访问不到,报404,此时资源的访问类似如下:

在服务器上可能会是如下,但访问一样可能会有问题。

我们可以将 publicPath 修改为相对路径,或者直接把它注释掉也行。

2.3.1、path和publicPath的区别

  • path 指定的是打包后文件在硬盘中的存储位置,是webpack所有文件的输出的路径,必须是绝对路径。比如:输出的js、图片,HtmlWebpackPlugin生成的html文件等,都会存放在以path为基础的目录下。
  • publicPath 并不会对生成文件的路径造成影响,主要是对你的页面里面引入的资源的路径做对应的补全。

2.4、output.chunkFilename(非入口chunk的名称)

output.chunkFilename 决定了非入口(non-entry) chunk 文件的名称。也就是除了入口文件生成的chunk外,其他文件生成的chunk文件命名。

module.exports = {
  //...
  output: {
    chunkFilename: 'js/[name]_chunk.js'   //非入口chunk的名称
  }
};

3、loader

webpack 本身只能打包 JavaScript 和 JSON 文件(webpack3+和webpack2+内置可处理JSON文件,但webpack1+并不支持,需要引入json-loader),这是 webpack 开箱可用的自带能力。webpack 本身不支持打包其他类型文件,比如 css、vue 等,但我们可以通过各种 loader 来让 webpack 去处理这些类型的文件。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL,loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

通过使用不同的loaderwebpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换 scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件。对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。

在 webpack 的配置中,loader 有两个属性:

  • test 属性,识别出哪些文件会被转换。

  • use 属性,定义出在进行转换时,应该使用哪个 loader。

  • include/exclude(可选):手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)

  • query(可选):为loaders提供额外的设置选项

//示例:webpack.config.js
const path = require('path');
module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [
        { test: /\.txt$/, loader: 'raw-loader' },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] }   //使用多个loader的话应该用 use
    ], 
  },
};