【Webpack】预处理器 - 常用loader介绍

选用合适的loader来处理不同的资源和不同的功能,以下是一些主流的loader,但这并不是全部,因为每时每刻都可能有新的loader 发布到 npm上

babel-loader

babe-loader 用来处理ES6+并将其编译为ESS,它使我们能够在最新的工程中使用最新语言特性,同时不必特别关注这些特性在不同平台的兼容问题

在安装时推荐使用以下命令:

npm install babel-loader /core /preset-env

在配置 babel-loader 时有一些需要注意的地方。请看下面的例子:

rules:[
{
	test: /\.js$/,
	exclude: /node_modules/,
	use:(
		loader: 'babel-loader',
		options:{
			cacheDirectory: true
			presets: [[
				'env'{
					modules; false,
				}
			]]},
	),
}
],

由于babel-loader通常属于对所有JS后缀文件设置的规则,所以需要在exclude中添加node_modules,否则会令 babel-loader 编译其中所有的模块,这将严重拖慢打包的速度,并且有可能改变第三方模块的原有行为。

对于babel-loader本身我们添加了cacheDirectory 配置项,它会启用缓存机制在重复打包未改变过的模块时防止二次编译,同样也会加快打包的速度。cacheDirector可以接收一个字符串类型的路径来作为缓存路径,这个值也可以为 true,此时其缓存目录会指向 node_modules/.cache/babel-loader

由于@babel/preset-env会将ES6 Module转化为CommonJS 的形式,这会导致 Webpack中的 tree-shaking 特性失效**@babel/preset-env的modules 配置项设置为false会禁用模块语的转化,而将ESModule的语法交给 Webpack 本身处理。**

ts-loader

ts-loader 与 babel-loader 的性质类似,它是用于连接Webpack 与 Typescript的模块。可使用以下命令进行安装:

npm install ts-loader typescript

Webpack 配置如下:

rules;[
	{
		test: /\.ts$/,
	    use:'ts-loader',
	}
],

需要注意的是,Typescript本身的配置并不在ts-loader 中,而是必须要放在工程录下的tsconfig.json中。
通过 Typescript 和 ts-loader,我们可以实现代码类型检查。

html-loader

html-loader用于将HTML文件转化为字符串并进行格式化,这使得我们可以把一个HTML片段通过JS加载进来

安装命令如下:

npm install html-loader

Webpack配置如下

rules;[
	{
		test: /\.html$/,
	    use:'html-loader',
	}
],

header.html将会转化为字符串,并通过 documentwrite 插人页面中

file-loader

file-loader 用于打包文件类型的资源,并返回其 publicPath。
安装命令如下:

npm install file-loader

Webpack配置如下

const path = require(path');
module.exports =(
	entry:'./app.js',
	output: {
		path: path.join(__dirname,'dist'),
		filename: 'bundle.js'},
	module:(
		rules:[
			{	
				test: /\.(png|jpg|gif)$/,
				use:'file-loader',
			}
		],
	},
};
		

4
上面我们对png、jpg、gif这类图片资源使用 file-loader,然后就可以在JS中加载图片了。

import avatarImage from './avatar.jpg';console.log(avatarImage);// c6f482ac9a1905e1d7d22caa909371fc.jpg

url-loader

url-loader 与 fle-loader 作用类似,唯一的不同在于用户可以设置一个文件大小阈值,当大于该阙傻时与 fle-loader一样返回 publicPath,而小于该值时则返回文件base64 形式编码。
安装命令如下:

npm install url-loader

Webpack 配置如下:

rules:[
	{
		test:/\.(png|jpg|gif)$/,
		use:{
			loader: 'url-loader',
			options:{
				limit: 10240,
				name: '[name].[ext]',
				publicPath: './assets-path/',
			}
		}
	}
]

url-loader 可接收与 file-loader 相同的参数,如name和 publicPath 等,同时也可以接收一个 limit 参数。

vue-loader

vue-loader 用于处理 vue 组件:

安装命令如下;

npm install vue-loader vue vue-template-compiler css-loader

Webpack配置如下

rules;[
	{
		test: /\.vue$/,
	    use:'vue-loader',
	}
],

自定义 loader

有时会遇到现有 loader 无法很好满足需求的情况,这时就需要我们对其进行修改或者编写新的 loader。如前面代码所演示的一样,loader 本身其实非常简单,下面就从头实现一个loader

我们将实现一个loader,它会为所有JS文件启用产格模式,也就是说它会在文件头部加上如下代码:

'use strict'

在开发一个loader时,我们可以借助 npm/yarn 的软链能进行本地调试(当然之后可以考发布到 npm等)。下面让我们初始化这个loader并配置到工程中。
创建一个 force-strict-loader 目录,然后在该目录下执行 npm初始化命令

npm init -y

接着创建 index.js,也就是 loader 的主体

module.exports = function(content){
	var useStrictPrefix = '\'use strict\';\n\n';
	return useStrictPrefix + content;
}

现在我们可以在 Webpack 工程中安装并使用这个 loader了。

npm install <path-to-loader>/force-strict-loader

在 Webpack工程目录下使用相对路径安装,会在项目的node modules 中创建一个指向实际 force-strict-loader 目录的软链,也就是说之后我们可以随时修改 loader源码并软链且不需要重复安装了。

下面修改 Webpack 配置

module:{
	rules:[
		{
			test:/\.js$/,
			use: 'force-strict-loader'
		}
	]
}

我们将这个loder设置为对所有JS 文件生效。此时对该工程进行打包应该可以看到JS文件的头部都已经加上了启用严格模式的语句。

启用缓存
当文件输入和其依赖没有发生变化时,应该让 loader 直接使用存,而不
行转换的工作。在 Webpack 中可以使用 his.cacheable 进行控制,修改我们的

module.exports = function(content){
	if(this.cacheable){
		this.cacheable();
	}
	var useStrictPrefix = '\'use strict\';\n\n';
	return useStrictPrefix + content;
}

通过启用缓存可以加快 Webpack 打包速度,并且可保证相同的输人产生输出。

获取options
前文讲过,loader的配置项通过 use.options 传进来,如:

rules:[
		{
			test:/\.js$/,
			use: {
				loader:'force-strict-loader',
				options:{
					sourceMap: true
				}
			}
		}
	]

上面配置了一个配置项sourceMap,接下来要再loader中获取,要先安装一个依库loader-utils,安装命令如下:

npm install loader-utils

loader更新如下

var loaderUtils = require("loader-utils");
module.exports = function(content){
	if(this.cacheable){
		this.cacheable();
	}
	var options = loaderUtils.getOptions(this) || {};
	var useStrictPrefix = '\'use strict\';\n\n';
	return useStrictPrefix + content;
}

通过loaderUtils.getOptions可以获取到配置对象

source-map
source-map可以便于实际开发者在浏览器控制台查看源码。如果没有对source-map进行处理,最终也就无法生成正确的 map 文件,在浏览器的 dev tool中可能就会看到错乱的源码。
下面是支持了source-map特性后的版本

var loaderUtils = require("loader-utils");
var SourceNode = require("source-map").SourceNode;
var SourceMapConsumer = reuqire("source-map").SourceMapConsumer;
module.exports = function(content){
	if(this.cacheable){
		this.cacheable();
	}
	var useStrictPrefix = '\'use strict\';\n\n';
	return useStrictPrefix + content;
	var options = loaderUtils.getOptions(this) || {};
	if (options.sourceMap && sourceMap) (
		var currentRequest = loaderutils.getCurrentRequest(this);
		var node = SourceNode.fromStringWithsourceMap(
			content,
			new SourceMapConsumer(sourceMap)
		);
		node.prepend(usestrictPrefix);
		var result = node.toStringWithSourceMap(( file: currentRequest ));
		var callback =this.async();
		callback(null,result.code,result.map.toJSON());
	}
	//不支持source-map情况
	return useStrictPrefix + content;
}

我们通过source-map这个库来对map进行操作,包括接收和消费之前的文件内容和source-map,对内容节点进行修改,最后产生新的source-map

在函数返回的时候要使用this.async获取 callback 函数(主要是为了一次性返回多个值)。callback函数的3个参数分别是抛出的错误、处理后的源码,以及source-map

你可能感兴趣的:(前端知识实践,webpack,前端,node.js)