webpack

概念

webpack就是一个用于javascript应用程序的静态模块打包工具
从v4版本开始,webpack就可以不用引入配置文件进行打包,但是,它仍然有着高度可配置性。

entry

入口起点指示webpack该使用的模块,作为构建内部依赖图的开始。进入起点之后,webpack会找出入口起点依赖的模块和库。默认是./src/index.js 可以指定一个或多个不同的起点。

单个入口

文件名:webpack.config.js

module.exports = {
  entry: './path/to/my/entry/file.js',
};

entry也能接收文件路径数组,这将创建一个所谓的 “multi-main entry”。在你想要一次注入多个依赖文件,并且将它们的依赖关系绘制在一个 “chunk” 中时,这种方式就很有用。

module.exports = {
  entry: ['./src/file_1.js', './src/file_2.js'],
  output: {
    filename: 'bundle.js',
  },
};

对象语法

module.exports = {
  entry: {
    app: './src/app.js',
    adminApp: './src/adminApp.js',
  },
};

写法比较繁琐,但是可见进行扩展
可扩展?

“webpack 配置的可扩展” 是指,这些配置可以重复使用,并且可以与其他配置组合使用。这是一种流行的技术,用于将关注点从环境(environment)、构建目标(build target)、运行时(runtime)中分离。然后使用专门的工具(如 webpack-merge)将它们合并起来。

描述入口对象的属性

  • dependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
  • filename: 指定要输出的文件名称。
  • import: 启动时需加载的模块。
  • library: 指定 library 选项,为当前 entry 构建一个 library。
  • runtime: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk
  • publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。请查看 output.publicPath。
module.exports = {
  entry: {
    a2: 'dependingfile.js',
    b2: {
      dependOn: 'a2',
      import: './src/app.js',
    },
  },
}

runtime 和 dependOn 不应在同一个入口上同时使用,所以如下配置无效,并且会抛出错误
为什么不能在同一个入口使用

runtime和dependOn都会从条目文件中删除运行时。一个原因是runtime将位于一个单独的文件中,以便其他实体可以重用它,另一个原因是运行时已经由依赖项加载。两者都没有意义,因为依赖关系在某种程度上会加载这个运行时。在同一个文件或运行时文件中,依赖项将加载它。如果希望同时指定依赖项并将运行时包含在单独的文件中,那么使用此示例,您必须在myEntry中指定myEntry属性,在mySecondEntry中指定dependOn属性

确保 runtime 不能指向已存在的入口名称,例如下面配置会抛出一个错误

module.exports = {
  entry: {
    a1: './a',
    b1: {
      runtime: 'a1',
      import: './b',
    },
  },
};

dependOn 不能是循环引用的,下面的例子也会出现错误

module.exports = {
  entry: {
    a3: {
      import: './a',
      dependOn: 'b3',
    },
    b3: {
      import: './b',
      dependOn: 'a3',
    },
  },
};

output

output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。

用法

output属性最低要求是将它的值设置为一个对象。

module.exports = {
  output: {
    filename: 'bundle.js',
  },
};

此配置将一个单独的 bundle.js 文件输出到 dist 目录中。

多个入口

如果配置中创建出多于一个 “chunk”,则应该使用 占位符(substitutions) 来确保每个文件具有唯一的名称。

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js',
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist',
  },
};

// 写入到硬盘:./dist/app.js, ./dist/search.js

loader

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

loader有俩属性:
test 属性,识别出哪些文件会被转换。
use 属性,定义出在进行转换时,应该使用哪个 loader。

const path = require('path');

module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
};

**注:**使用正则表达式匹配文件时,你不要为它添加引号。也就是说,/.txt / 与 ′ / t ˙ x t / 与 '/\.txt //t˙xt/’ 或 “/.txt$/” 不一样,前者指示 webpack 匹配任何以 .txt 结尾的文件,后者指示 webpack 匹配具有绝对路径 ‘.txt’ 的单个文件

plugin

loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建一个插件实例。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件

module.exports = {
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })]
  //html-webpack-plugin 为应用程序生成一个 HTML 文件,并自动将生成的所有 bundle 注入到此文件中。
};

关于插件

webpack 插件是一个具有 apply 方法的 JavaScript 对象。apply 方法会被 webpack compiler 调用,并且在 整个 编译生命周期都可以访问 compiler 对象。
ConsoleLogOnBuildWebpackPlugin.js

const pluginName = 'ConsoleLogOnBuildWebpackPlugin';

class ConsoleLogOnBuildWebpackPlugin {
  apply(compiler) {
    compiler.hooks.run.tap(pluginName, (compilation) => {
      console.log('webpack 构建正在启动!');
    });
  }
}

module.exports = ConsoleLogOnBuildWebpackPlugin;

compiler hook 的 tap 方法的第一个参数,应该是驼峰式命名的插件名称。建议为此使用一个常量,以便它可以在所有 hook 中重复使用。

Configuration

webpack 的配置文件是 JavaScript 文件,文件内导出了一个 webpack 配置的对象。
webpack 会根据该配置定义的属性进行处理。
在配置中使用:

通过 require(…) 引入其他文件 通过 require(…)
使用 npm 下载的工具函数
使用 JavaScript 控制流表达式,例如 ?: 操作符
对 value 使用常量或变量赋值
编写并执行函数,生成部分配置

应该避免如下操作

  • 当使用 webpack CLI 工具时,访问 CLI 参数(应编写自己的 CLI 工具替代,或者使用 --env)
  • 导出不确定的结果(两次调用 webpack 应产生相同的输出文件)
  • 编写超长的配置(应将配置文件拆分成多个)

基本配置

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js',
  },
};

模块

概念

模块是程序分解为功能离散的chunk
与 Node.js 模块相比,webpack 模块能以各种方式表达它们的依赖关系。下面是一些示例:

  • ES2015 import 语句
  • CommonJS require() 语句
  • AMD define 和 require 语句
  • css/sass/less 文件中的 @import 语句。
  • stylesheet url(…) 或者 HTML 文件中的图片链接。

支持的模块

Webpack 天生支持如下模块类型:

  • ECMAScript 模块
  • CommonJS 模块
  • AMD 模块
  • Assets
  • WebAssembly 模块

解析模块

resolver 是一个帮助寻找模块绝对路径的库。 一个模块可以作为另一个模块的依赖模块,然后被后者引用,如下:

import foo from 'path/to/module';
// 或者
require('path/to/module');

所依赖的模块可以是来自应用程序的代码或第三方库。 resolver 帮助 webpack 从每个 require/import 语句中,找到需要引入到 bundle 中的模块代码。 当打包模块时,webpack 使用 enhanced-resolve 来解析文件路径。

解析规则

使用 enhanced-resolve,webpack 能解析三种文件路径:
绝对路径

import '/home/me/file';

import 'C:\\Users\\me\\file';

相对路径

import '../src/file1';
import './file2';

在这种情况下,使用 import 或 require 的资源文件所处的目录,被认为是上下文目录。在 import/require 中给定的相对路径,会拼接此上下文路径,来生成模块的绝对路径。
模块路径

import 'module';
import 'module/lib/file';

解析 loader
loader 的解析规则也遵循特定的规范。但是 resolveLoader 配置项可以为 loader 设置独立的解析规则。

target

用法

想设置 target 属性,只需在 webpack 配置中设置 target 字段:
webpack.config.js

module.exports = {
  target: 'node',
};

在上述示例中,target 设置为 node,webpack 将在类 Node.js 环境编译代码。(使用 Node.js 的 require 加载 chunk,而不加载任何内置模块,如 fs 或 path)。

每个 target 都包含各种 deployment(部署)/environment(环境)特定的附加项,以满足其需求。具体请参阅 target 可用值。

多个target
虽然 webpack 不支持 向 target 属性传入多个字符串,但是可以通过设置两个独立配置,来构建对 library 进行同构:

const path = require('path');
const serverConfig = {
  target: 'node',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.node.js',
  },
  //…
};

const clientConfig = {
  target: 'web', // <=== 默认为 'web',可省略
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.js',
  },
  //…
};

module.exports = [serverConfig, clientConfig];

上述示例中,将会在 dist 文件夹下创建 lib.js 和 lib.node.js 文件。

总结

webpack的打包结果里,实现了一套基于 webpack_require 和 webpack exports对象的一套模块化规范,通过把我们源码中的一个一个的文件, 做为一个一个的 key + function的形式存储进webpack_modules里, 同时会把我们在源码中写的所有模块化规范, 都改成webpak_require,以及改成他自己的exports ,加载的时候 就是执行对应的webpack_modules里的对应key的函数 ,这个函数执行完成以后就会把对应的exports对象里写满值 ,默认导出就会有一个default属性在expoprts对象上 具名导出就是具体的kev在exports对象上。

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值