Webpack Loader种类以及执行顺序
我们在用webpack构建项目的时候,有两种配置打包文件的方式:
- import或者require :a-loader!b-loader!.././static/dog.png(打包某一个文件)
- 配置webpack.config.js文件的module.rules(打包某一类的文件)
针对于以上的第二种方式我贴下我之前一篇博客中的配置 Vue动态注册异步组件(非同一个工程的组件)
var path = require('path')
var webpack = require('webpack') module.exports = {
entry: process.NODE_ENV === 'development' ? './src/main.js' : './src/component/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'async-component.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
} if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
// new webpack.optimize.UglifyJsPlugin({
// sourceMap: true,
// compress: {
// warnings: false
// }
// }),
new webpack.LoaderOptionsPlugin({
minimize: false
})
])
}
对单文件打包的方式的loader被称为行内(inline)loader;对于rules中的loader,webpack还定义了一个属性 enforce,可取值有 pre(为pre loader)、post(为post loader),如果没有值则为(normal loader)。所以loader在webpack中有4种:normal,inline,pre,post。
贴下官方源码地址 :Loader Type
for (const r of result) {
if (r.type === "use") {
if (r.enforce === "post" && !noPrePostAutoLoaders) {
useLoadersPost.push(r.value);
} else if (
r.enforce === "pre" &&
!noPreAutoLoaders &&
!noPrePostAutoLoaders
) {
useLoadersPre.push(r.value);
} else if (
!r.enforce &&
!noAutoLoaders &&
!noPrePostAutoLoaders
) {
useLoaders.push(r.value);
}
} else if (
typeof r.value === "object" &&
r.value !== null &&
typeof settings[r.type] === "object" &&
settings[r.type] !== null
) {
settings[r.type] = cachedCleverMerge(settings[r.type], r.value);
} else {
settings[r.type] = r.value;
}
}
所有的loader的执行顺序都有两个阶段:pitching和normal阶段,类似于js中的事件冒泡、捕获阶段(有人嫌官方的词描述的比较晦涩,修改为loader的标记阶段(mark stage)和执行阶段(execution/run stage))。
对于第二种方式的解释:webpack 官方解释
- Pitching阶段: post,inline,normal,pre
- Normal阶段:pre,normal,inline,post
我看有大神的解释如下:(很好理解)
It's like the two phases of event bubbling... a!b!c!resource pitch a
pitch b
pitch c
read file resource (adds resource to dependencies)
run c
run b
run a
When a loader return something in the pitch phase the process continues with the normal phase of the next loader... Example: pitch a
pitch b (returns something)
run a
对应的方式1解析loader的源码:
let elements = requestWithoutMatchResource
.replace(/^-?!+/, "")
.replace(/!!+/g, "!")
.split("!");
对应的方式2解析loader的源码:
const result = this.ruleSet.exec({
resource: resourcePath,
realResource:
matchResource !== undefined
? resource.replace(/\?.*/, "")
: resourcePath,
resourceQuery,
issuer: contextInfo.issuer,
compiler: contextInfo.compiler
});
那么问题来了,如果我们采用了两种解析loader的方式,他们的执行是什么样的呢?答案是inline loader优先级高于config配置文件中的loader:源码
webpack使用了neo-async库(用来提供js异步编程的工具库)来解析loader模块,解析inline loader的源码,
解析config loader的源码
webpack官方文档推荐不适用inline loader,最好用在配置文件中使用loader(注意:loader处理的代码中是含有inline loader的)。另外,在特殊情况下我我们可以在inline loader间接改变loader的执行顺序(禁止某些另外3种loader),比如在我们的自己公司某个同事的不是很规范的js库在引入的时候需要禁止掉eslint-loader对其进行处理
- 加入 ! 前缀禁用配置文件中的普通loader,比如:
require("!raw!./script.coffee")
- 加入 !! 前缀禁用配置文件中所有的loader,比如:
require("!!raw!./script.coffee")
- 加入 -! 前缀禁用配置文件中的pre loader和普通loader,但是不包括post loader,比如:
require("!!raw!./script.coffee")
关于loader的禁用,webpack官方的建议是:除非从另一个loader处理生成的,一般不建议主动使用
- pre loader 配置:图片压缩
- 普通loader 配置:coffee-script转换
- inline loader 配置:bundle loader
- post loader 配置: 代码覆盖率工具
Webpack Loader种类以及执行顺序的更多相关文章
- 如何开发webpack loader
关于webpack 作为近段时间风头正盛的打包工具,webpack基本占领了前端圈.相信你都不好意思说不知道webpack. 有兴趣的同学可以参考下我很早之前的webpack简介 . 确实webpac ...
- 手把手教你撸一个 Webpack Loader
文:小 boy(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 经常逛 webpack 官网的同学应该会很眼熟上面的图.正如它宣传的一样,webpack 能把左侧各种类型的文件(webpa ...
- webpack loader实现
正值前端组件化开发时代,那么必然离不开目前最火的构建工具--webpack(grunt,gulp等暂且不谈).说到这里,刚好有几个问题: 为什么运行打包命令之后,.vue 文件可以转成 .js 文件 ...
- 揭秘webpack loader
前言 Loader(加载器) 是 webpack 的核心之一.它用于将不同类型的文件转换为 webpack 可识别的模块.本文将尝试深入探索 webpack 中的 loader,揭秘它的工作原理,以及 ...
- webpack loader & pulgin
webpack loader & plugin https://webpack.js.org/concepts/loaders/ https://webpack.js.org/concepts ...
- 浅析js的执行顺序
javascript是一种描述型的脚本语言,是一种解析语言,由浏览器动态解析,不同种类的浏览器不同版本的浏览器对于js的解析有着微小的差别,不同浏览器的js解析引擎效率也有高低,下面来给大家分析一下j ...
- (转)java for循环的执行顺序和几种常用写法
算是温习吧.问题比较基础,但是也比较重要.(虽然是C,但是很经典) for循环可以说在每个程序中都少不了的,语句头包括三个部分:初始化,判读条件,一个表达式. 但是这三个部分的执行顺序是什么,这是我们 ...
- python接口自动化(二十二)--unittest执行顺序隐藏的坑(详解)
简介 大多数的初学者在使用 unittest 框架时候,不清楚用例的执行顺序到底是怎样的.对测试类里面的类和方法分不清楚,不知道什么时候执行,什么时候不执行.虽然或许通过代码实现了,也是稀里糊涂的一知 ...
- 转:Filter的执行顺序与实例
转:http://www.cnblogs.com/Fskjb/archive/2010/03/27/1698448.html Filter的执行顺序与实例 Filter介绍 Filter可认为是Ser ...
随机推荐
- 转:HTML5 History API 详解
从Ajax翻页的问题说起 请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评论.正当你想要停下滚轮细看的时候,手残按到了F5.然后,页面刷新了,评论又回到了第一页 ...
- Spring——框架
[定义] 框架就是制定一套规则或规范(思想),大家(程序员)在该规范或者规则(思想)下工作. 或者说是使用别人搭好的舞台,你来表演. [特点] ——半成品 ——封装了特定的处理流程和控制逻辑 ——成熟 ...
- ubantu apache2.4.6 apache https配置
[root@VM_58_118_centos dbback]# a2enmod ssl [root@VM_58_118_centos dbback]# service apache2 restart ...
- Android Bluetooth 文件接收路径修改方法
修改文件: packages/apps/Bluetooth/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java 相关代码片段: ...
- Java数据结构与算法(4):二叉查找树
一.二叉查找树定义 二叉树每个节点都不能有多于两个的儿子.二叉查找树是特殊的二叉树,对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项. 二叉查找树节点的 ...
- MySQL多表查询合并结果union all,内连接查询
MySQL多表查询合并结果和内连接查询 1.使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tab ...
- pepflashplayer32_25_0_0_127.dll: 0x59952C6D is not a valid instance ID.
pepflashplayer32_25_0_0_127.dll: 0x59952C6D is not a valid instance ID. . 点进去是提示doctype错误 暂时没有解决---- ...
- MySQL主主模式
mysql主主复制配置: HOSTNAME IPADDR PORT节点1:my-prod01.oracle.com 192.168.10.97 3306 节点2:my-prod02.oracle.co ...
- VMware 接入 Openstack — 使用 Openstack 创建 vCenter 虚拟机
目录 目录 软件环境 前言 Openstack 接口驱动 使用 KVM 在 Compute Node 上创建虚拟机的流程 使用 VCDirver 在 vCenter 上创建虚拟机的流程 配置 vCen ...
- Week4 - 500.Keyboard Row & 557.Reverse Words in a String III
500.Keyboard Row & 557.Reverse Words in a String III 500.Keyboard Row Given a List of words, ret ...