webpack
webpack
JavaScript 应用程序的静态模块打包器(static module bundler)
在处理应用程序时,会在内部创建一个依赖图 dependency graph
映射到项目需要的每个模块,将所有这些依赖生成到一个或多个 bundle
用来作为构建内部依赖图的开始
webpack.config.js
entry #输入 output
创建 bundles 存放的文件
处理非 js 文件
rules 用什么插件进行处理
用于转换非 js 文件先 require 安装然后再 new 创建一个实例
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
分离应用程序 app 和第三方 vendor 入口
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
每个 bundle 中都有一个 bootstrap
多页面应用程序
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
output: {
filename: 'bundle.js', //文件名
path: '/home/proj/public/assets' //绝对路径
}
多入口
配置创建多个单独的 chunk
使用多个入口起点或 CommonsChunkPlugin 的插件
应该使用占位符确保每个文件具有唯一的名称
filename: '[name].js',
mode: 'production'
从cli参数中传递
webpack --mode=production
用于对模块的源代码进行转换
loader可以再import 或加载模块时预处理文件
将内联图像转换为data URL
使用方式
配置:在webpack.config.js文件中指定loader
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
内联:在每个import语句中显式指定loader
import Styles from 'style-loader!css-loader?modules!./styles.css';
import 语句,或任何等效import的方式中指定loader
使用!将资源中的loader分开
cli:在shell命令中指定
支持链式传递,loader链中每个loader,都对前一个loader处理后的资源进行转换.
loader可以是同步的,也可以是异步的
loader运行再nodes.js中,并且能够执行任何可能的操作
loader接收查询参数,用于对loader 传递配置
loader也能够使用options对象进行配置
除了使用package.json常见的main属性,还可以将普通的npm模块导入loader,做法是在package.json里定一个loader字段
loader 将从模块路径解析
插件是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 构建过程开始!');
});
}
}
compiler hook的tap方法的第一个参数,它可以在所有hook中复用
插件可以携带参数/选项,必须再webpack配置中,向plugins属性传入 new 实例
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
const webpack = require('webpack'); //访问内置的插件
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
webpack的配置文件,是导出一个对象的javascript文件
webpack根据对象定义的属性进行解析
webpack配置是标准的Node.js CommonJS模块
- 通过require()导入其他文件
- require()使用npm的工具函数
- 使用JavaScript控制流表达式 ?:操作符
开发者将程序分解成离散功能块 discrete chunks of functionality
node.js支持模块化编程
解析规则
- 绝对路径
- 相对路径
- 模块路径
指向文件
- 如果路径具有文件扩展名,则直接被打包
- 否则,使用resolve.extensions选项作为文件扩展名解析
- 此选项告诉解析器在解析中能够接受那些扩展名
指向文件夹
- 文件加中包含package.json文件,则按照顺序查找 resolve.mainFields配置选项中指定的字段,
- 并且package.json中的第一个这样的字段确定文件路径
则按照顺序查找 resolve.mainFiles配置选项中指定的文件名
文件扩展名通过resolve.extensions 选项采用类似的方法进行解析
一个文件依赖于另一个文件,
webpack就视为文件之间有依赖关系
可以接受非代码资源,并且可以把他们作为依赖提供给你的应用程序
构建的典型应用程序或站点中,主要有三种
- 你或你的团队编写的源码
- 源码会依赖的任何第三发的library或vendor代码
- webpack的runtime和manifest,管理所有模块的交互
在浏览器运行时,webpack用来连接模块化的应用程序的所有代码
runtime包含:
在模块交互时,连接模块所需的加载和解析逻辑
包括浏览器中的已加载模块的连接,以及懒加载模块的执行逻辑
manifest数据用来管理生成的index.html文件和bundle以及各种资源,把他们加载到浏览器中
当编译器开始执行、解析和映射应用程序,会保留所有模块的详细要点.
这个集合称为Manifest
打包完成发送到浏览器
运行时通过Manifest来解析和加载模块
import 或require语句转换为 webpack require 方法
此方法指向模块标识符
通过manifest 中的数据
runtime 将能够查询模块标识符,检索出背后对应的模块
使用webpack 会编译为用于类nodes.js环境,而不是使用任意内置模块
可以通过打包两份分离的配置来创建同构的库
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 ];
显著加快开发速度