Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack之坑位整理 #32

Open
RachelRen opened this issue May 21, 2019 · 0 comments
Open

Webpack之坑位整理 #32

RachelRen opened this issue May 21, 2019 · 0 comments

Comments

@RachelRen
Copy link
Owner

webpack

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

  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的�区别?

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

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作为应用程序中的文件。

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 **必须设置为 true Boolean
ignoreOrder 禁用插件 Boolean
disable 禁用顺序检查 (这对 CSS 模块很有用!),默认 false Boolean

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基本配置项总结

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant