webpack
标签(空格分隔): webpack
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
webpack4新特性
1.mode属性
webpack需要设置mode属性,可以是development或production。例如:webpa --mode development
Webpack针对开发者模式提供的特性:
- 浏览器调试工具
- 注释、开发阶段的详细错误日志和提示
- 快速和优化的增量构建机制
Webpack针对生产者模式提供的特性:
- 开启所有的优化代码
- 更小的bundle大小
- 去除掉只在开发阶段运行的代码
- Scope hosting和Tree-shaking
2.插件和优化
webpack4删除了CommonsChunkPlugin插件,他使用内置API optimization.splitChunks和optimization.runtimeChunk,这意味着webpack会默认为你生成共享代码块
3.开箱即用WebAssembly
WebAssembly(wasm)会带来运行时性能的大幅提升,由于在社区的热度,webpack4对他做了开箱即用的支持。你可以直接对本地的wasm模块进行import或者export操作,也可以通过编写loaders来直接import C++、C或者rust
4.支持多种模块类型
- JavaScript/auto: 在webpack3里,默认开启对所有模块的系统支持,包括CommonJS、AMD、ESM
- JavaScript/esm : 只支持ESM这种静态模块
- JavaScript/dynamic:只支持CommonJS和Amd这种静态模块。
- json:只支持JSON数据,可以通过require和import来使用。
- webassembly/experimental: 只支持wasm模块,目前处于实验阶段。
5.0CJS
0CJS的含义是0配置,webpack4受Parcel打包工具启发,尽可能的让开发者运行项目的成本变低,为了做到0配置,webpack4不再强制需要webpack.config.js作为打包配置的入口文件了,它默认的入口为’./src/‘和默认出口’./dist’,对小型项目来说是福音。
6.新的插件系统
webpack4对插件系统进行了不少修改,提供了针对插件和钩子的新APl。
变化如下:
- 所有的hook由hooks对象统一管理,它将所有的hook作为可扩展的类属性。
- 当添加插件时,必须提供一个插件名称。
- 开发插件时,可以选择sync/calback/promise作为插件类型
- 可以通过this.hooks={myHook:new SyncHook(.…)}来注册hook了.
注意点:当使用webpack4时,确保使用Node.js的版本>=8.9.4.因为webpack4使用了很多新的语法,它们在新版本的v8里经过了优化。
入口出口配置
配置文件:webpack.config.js
const path = require('path');
module.exports = {
entry:'./input.js', //入口
output:{
path:path.resolve(_dirname,'dist'),
filename:'output.bundle.js'
}//出口
}
//也可以通过键值对的方式设置多个入口出口
const path = require('path');
module.exports = {
entry:{
home:'./home.js',
about:'./about.js',
other:'./other.js'
},
output:{
path:path.resolve(__dirname,'dist'),
filename: '[name].bundle.js'
},
mode:"production" //通过mode设置生产者/开发者模式
}
loaders
webpack处理源文件进行预处理的方式
url-loader:
将图片文件转换为base64编码并载入浏览器能够减少http请求数,但是增大了js或html文件的体积,如果图片在项目中的重用度较高,那么每处引用都会生成base64编码,造成了代码的冗余。通过http请求载入到浏览器的文件可以缓存到本地,当图片在项目中的重用度较高时,会为图片的访问增加缓存的便利性,下次访问更快。因此要平衡考虑。
//url-loader:
$ npm install url-loader --save-dev
// index.js
import img from './image.png';
//webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
//边界大小,大于边界保存为普通文件,小于边界转化为base64码
},
},
],
},
],
},
};
//And run webpack via your preferred method.
babel-loader:
将es6,es7代码转换为浏览器可以识别的es5代码
//babel-loader:
$ npm install -D babel-loader @babel/core @babel/preset-env webpack
//webpack.config.js
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
sass-loader
处理sass,会将css代码和js打包到一起,并不是很好的方法
//sass-loader:
$ npm install sass-loader node-sass webpack --save-dev
//app.js
import './style.scss';
//style.scss
$body-color: red;
body {
color: $body-color;
}
//webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
};
plugins
MiniCssExtractPlugin
为每个引入CSS的JS文件创建一个CSS文件
//install
npm install --save-dev mini-css-extract-plugin
//webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
],
},
],
},
};
DefinePlugin
将 DefinePlugin允许您创建可在配置全局常量的编译时间。这对于在开发版本和生产版本之间允许不同的行为很有用。如果在开发版本中而不是生产版本中执行日志记录,则可以使用全局常量来确定是否进行日志记录。那就是DefinePlugin闪耀的地方,设置它并忘记它的开发和生产构建规则。`
new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify('https://dev.example.com')
});
##HtmlWebpackPlugin
该HtmlWebpackPlugin简化创建HTML文件,以满足您的WebPack束。这对于webpack捆绑包特别有用,该捆绑包的文件名中包含哈希值,该哈希值会更改每次编译。您可以让插件为您生成一个HTML文件,使用lodash模板提供您自己的模板,或者使用您自己的loader。
//安装
npm install --save-dev html-webpack-plugin
//该插件将为您生成一个HTML5文件,其中会使用script标签将您的所有Webpack捆绑包包括在内。
//webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};