Webpack的坑位整理

webpack

webpack现在是主要的打包工具了,现在网络上也有很多资料可以学习了。这里主要整理了一些基础概念,但没有所有的写,只是把之前遇到的问题记录了一下。

本文的原文在我的博客中:github.com/RachelRen/b…

欢迎star

  1. 概念
  2. 基本概念
  3. 简单配置
  4. 优化

概念

webpack是一个js应用程序的模块化打包器,它将递归地构建一个依赖关系图,其中包括应用程序需要的每个模块,然后将所有模块打包成少量的bundle.

entry

这个告诉webpack从哪里开始,并根据依赖关系图确定需要打包的内容。

module.exports = {
	entry: './src/app/index.js'
}
复制代码
语法

单个入口 entry: string|Array<string> 当这个entry中传入数组时,就是创建了多个住入口。

对象语法 entry: {[entryChunkName: string]: string|Array<string>}entry:{[]} 这种比较繁琐,但是这种方法是最可扩展的。

context

Webpack 在寻找相对路径的文件时会以 context 为根目录,context 默认为执行启动webpack时所在的当前目录。

module.exports = {
  context: path.resolve(__dirname, 'app')
}
复制代码

output

告诉webpack在哪里打包应用程序

	output: {
	    path: path.resolve(__dirname, 'build'),
	    filename: 'js/[name].js',
	    publicPath: '/',
	    chunkFilename:'js/[name].chunk.js',
		//chunkFilename:'js/[name].[chunkhash:8].chunk.js',
	},

复制代码

这里 filename chunkFilename的区别?

chunkhashhash 的区别?

每次输出都有什么样的配置呢?

详情请看我的另一篇博客 webpack之输出

loader

因为webpack自身只理解Javascript,但是程序本身也需要处理(.css, .html, .scss, .jpg,etc.),所以webpack把这些文件都作为模块来处理。 webpack loader在文件被添加到依赖图中时,将其转换称为了模块。webpack配置loader中的两个目标。

  1. 识别出(identify)应该被对应的loader进行转换的那些文件(test属性)
  2. 转换这些文件,从而使其能够被添加到依赖图中,并且最终添加到bundle中(use属性)
module.exports = {
	module: {
		rules: [
			 test: /\.html?$/,
	        use: {
	          loader: 'html-loader'
	        }
		]
	}
}
复制代码

use可以跟一个数组,表示指定多个loader

loader的特性

  • loader可以时同步的,也可以是异步的
  • 接受查询参数,用于对loader传递配置
  • 能够使用 options对象进行配置
  • 除了使用package.json常见的main属性,还可以将普通的npm模块导出为loader,做法是在packago.json里定义一个loader字段
  • 插件可以为loader带来更多特性

loader 模块需要导出为一个函数,并且使用Node.js兼容的Javascript编写。通常使用npm进行管理,但是也可以将自定义loader作为应用程序中的文件。

关于loader的具体的详细特征,可以看我的另一篇博客:webpack之Loader

plugins

因为loader只是每个文件的基本转换,但是plugins主要用于在打包模块的“compilation”和“chunk”生命周期执行操作和自定义功能。使用插件需要require()它,然后把它添加到plugins的数组中,多数插件可以通过选项(option)自定义,也可以在一个配置文件中因为不同目的而多次使用同一个插件。

const config = {
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};
复制代码

插件是一个具有apply属性的javascript对象,apply属性会被webpack compiler调用,并且compiler对象可在整个编译生命周期访问。

配置

webpack配置文件是导出一个对象的javascript文件,他是标准的nodejs CommonJs模块,可以做以下事情

  • 通过require(...)导入其他文件
  • 通过require(...)使用npm的工具函数
  • 使用JavaScript控制流表达式,如?:操作符
  • 编写并执行函数来生成部分配置

常用插件

ExtractTextPlugin

遇到的问题

参数说明类型
id此插件实例的唯一 ident。(仅限高级用途,默认情况下自动生成)String
filename生成文件的文件名。可能包含 [name], [id] and [contenthash]string
allChunks从所有额外的 chunk(additional chunk) 提取(默认情况下,它仅从初始chunk(initial chunk) 中提取)
当使用 CommonsChunkPlugin 并且在公共 chunk 中有提取的 chunk(来自ExtractTextPlugin.extract)时,allChunks **必须设置为 trueBoolean
ignoreOrder禁用插件Boolean
disable禁用顺序检查 (这对 CSS 模块很有用!),默认 falseBoolean

extrat

ExtractTextPlugin.extract(options: loader | object)

从一个已存在的 loader 中,创建一个提取(extract) loader。支持的 loader 类型 { loader: [name]-loader -> {String}, options: {} -> {Object} }。

名称类型描述
options.use{String}/{Array}/{Object}loader 被用于将资源转换成一个 CSS 导出模块 (必填)
options.fallback{String}/{Array}/{Object}loader(例如 'style-loader')应用于当 CSS 没有被提取(也就是一个额外的 chunk,当 allChunks: false)
options.publicPath{String}重写此 loader 的 publicPath 配置

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
	module: {
		rules: [
			{
				test: /\.css$/,
				use: ExtractTextPlugin.extract({
					fallback: 'style-loader',
					use: [{
						loader: 'css-loader',
						options: {
							importLoaders: 1
						}
					}]

				})

			},
			{
				test: /\.scss?$/,
				use: ExtractTextPlugin.extract({
					fallback: 'style-loader',
					use: [{
						loader: 'css-loader',
					}, {
						loader: 'postcss-loader',
						options: {
							plugins: [require('autoprefixer')({
									broswers: ['last 3 version', 'ie >= 10']
								})]
						}
					}, {
						loader: 'sass-loader',

					}]

				})
			}
		],
		plugins: [
			new ExtractTextPlugin({
			filename: 'style.css', 
			allChunks: true,
			ignoreOrder: false,
			disable: false
		}),
		]
	}
}
复制代码

HtmlWebpackPlugin

可以用这个插件生成一个html文件,使用lodash模版提供的模版,或者使用自己的loader

基本用法

var HtmlWebpackPlugin = require('html-webpack-plugin');

var webpackConfig = {
  entry: 'index.js',
  output: {
    path: 'dist',
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin()]
};

复制代码

将生成一个/dist/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>webpack App</title>
  </head>
  <body>
    <script src="index_bundle.js"></script>
  </body>
</html>
复制代码

也可以使用模版,产生html,并将css插入到html中

new HtmlWebpackPlugin({
	filename: 'index.html',
	template: paths.appHtml,
	// template: __dirname + '/src/app/index.html',
	inject: true,
	chunks: ['vendor', 'index'], //会自动将js文件插入html中
	chunksSortMode: 'dependency'
}),
复制代码

CommonsChunkPlugin

是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块.通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存起来到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。

new webpack.optimize.CommonsChunkPlugin({
			name: 'vendor',
			filename: 'vendor.bundle.js' //gave the chunk a different name
		}),
		
复制代码

使用 CommonsChunkPlugin 为每个页面间的应用程序共享代码创建 bundle。由于入口起点增多,多页应用能够复用入口起点之间的大量代码/模块,从而可以极大地从这些技术中受益。

不过这个插件在Webpack 4 后就不用了。

webpack 4.0

  1. extract-text-webpack-plugin 不再支持

  2. 构建模式mode,必须配置这个属性

  3. 公共代码提取:将CommonsChunkPlugin 直接改为optimization.splitChunks和optimization.runtimeChunk这两个配置。

  4. 压缩上

    压缩插件更新到 uglifyjs-webpack-plugin 1.0 版本,支持多进程压缩,缓存以及es6语法,无需单独安装转换器。当 mode='production' 默认开启压缩,无需配置。可以通过 optimization.minimize 和 optimization.minimizer 自定义配置。测试发现,第二次打包时间是第一次打包的一半左右

Webpack 4 配置最佳实践 webpack基本配置项总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值