本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle
在webpack中一切文件皆模块,通过loader转换文件,通过plugins注入钩子,最后输出由多个模块组成的文件.
Webpack的优点:
1.专注于模块化处理的项目,能做到开箱即用,一步到位
2.可通过Plugin扩展,完整好用又不是灵活
3.使用场景不仅仅局限于web开发
4.社区活跃,经常引入紧跟时代的xin特性,能为大多数的开发场景找到已有的开源扩展
5.良好的开始体验
安装webpack
#npm i -D [npm install --save--dev安装到package.json]文件中
#npm i -D webpack 安装到最新版本
#npm i -D webpack@<version> 指定️版本安装
#npm i -D webapck@beta 安装到最新体验版
#npm i -g webpack 安装到全局
##概念
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值是 ./src/index.js,但你可以通过在 webpack configuration 中配置 entry 属性,来指定一个(或多个)不同的入口起点。例如:
webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
多入口打包
var path = require('path');
module.exports = {
entry: {
bundle:'./main.js',
bundle1: './main1.js'
},
output: {
path: path.resolve(__dirname, 'dist/demo'),
filename: '[name].[hash].js'
}
};
输出(output)
output 属性告诉 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'
}
}
loader
webpack 只能理解 JavaScript 和 JSON 文件。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
在更高层面,在 webpack 的配置中 loader 有两个属性:
test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
use 属性,表示进行转换时,应该使用哪个 loader。
webpack.config.js
module: {
rules: [
{
test: /.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015','react']
}
}
},
{
test: /.css$/,
use: ['style-loader', 'css-loader']
}
]
}
以上配置中,对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:test 和 use
loader用于对模块的源代码进行转换。loader可以是你再import 或者 ‘加载’模块时候进行预处理文件。因此。loader类似于其他构建工具中的‘任务(task)’,并提供了处理前端构建步骤的强大方法。loader可以将文件从不同的语言(Typescript) 转为js 或者将内敛图像转化为data URL。loader甚至允许你直接在js模块中import css文件
例子
例如,你可以使用 loader 告诉 webpack 加载 CSS 文件,或者将 TypeScript 转为 JavaScript。为此,首先安装相对应的 loader:
npm install --save-dev css-loader
npm install --save-dev ts-loader
然后指示 webpack 对每个 .css 使用 css-loader,以及对所有 .ts 文件使用 ts-loader:
webpack.config.js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
使用的方式
在你的应用程序中,有三种使用 loader 的方式:
* 配置(推荐):在 webpack.config.js 文件中指定 loader。
* 内联:在每个 import 语句中显式指定 loader。
* CLI:在 shell 命令中指定它们。
配置【configuration】
module.rules 允许你在 webpack 配置中指定多个 loader。 这种方式是展示 loader 的一种简明方式,并且有助于使代码变得简洁和易于维护。同时让你对各个 loader 有个全局概览:
loader 从右到左地取值(evaluate)/执行(execute)。在下面的示例中,从 sass-loader 开始执行,然后继续执行 css-loader,最后以 style-loader 为结束。查看 loader 功能 了解有关 loader 顺序的更多信息。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
},
{ loader: 'sass-loader' }
]
}
]
}
};
loader 特性
loader 支持链式传递。链中的每个 loader 会将转换应用在已处理过的资源上。一组链式的 loader 将按照相反的顺序执行。链中的第一个 loader 将其结果(也就是应用过转换后的资源)传递给下一个 loader,依此类推。最后,链中的最后一个 loader,返回 webpack 期望 JavaScript。
loader 可以是同步的,也可以是异步的。
loader 运行在 Node.js 中,并且能够执行任何 Node.js 能做到的操作。
loader 可以通过 options 对象配置(仍然支持使用 query 参数来设置选项,但是这种方式已被废弃)。
除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块。
插件(plugin)可以为 loader 带来更多特性。
loader 能够产生额外的任意文件。
插件(plugin)
插件是 webpack 的 支柱 功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!
插件目的在于解决 loader 无法实现的其他事。
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
webpack.config.js
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 webpack.ProgressPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
模式(mode)
通过选择 development, production 或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production。
module.exports = {
mode: 'production'
};
如果根据webpack.config.js 种的mode变量改变打包行为,则必须将配置导出为一个函数。而不是导出一个对象。
var config = {
entry: './app.js'
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};
模块热更替【hot module replacement】
模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除 模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:
保留在完全重新加载页面期间丢失的应用程序状态。
只更新变更内容,以节省宝贵的开发时间。
在源代码中对 CSS/JS 进行修改,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式。