shimming 将一个新的 API 引入到一个旧的环境中,而且仅靠旧的环境中已有的手段实现。
ProvidePlugin 我们在程序中暴露一个变量,通知webpack某个库被使用,webpack将在最终的bundle中引入该库。
// index.js
function component() { var element = document.createElement('div'); element.innerHTML = _.join(['hello','webpack'],' '); return element; } document.body.appendChild(component());
注意,这个文件里不需要import _ from lodash了
// webpack.common.js
plugins:[ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'shimming' }), + new webpack.ProvidePlugin({ + _: 'lodash' + }) ]
还可以利用ProvidePlugin暴露库中的单一函数(变量)
function component() { var element = document.createElement('div'); element.innerHTML = join(['hello','webpack'],' '); return element; } document.body.appendChild(component());
plugins:[ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'shimming' }), new webpack.ProvidePlugin({ + join: ['lodash','join'] }) ]
这样,就可以将lodash库中的其他没用到的部分去除。(tree shaking)
注意:任何需要AST的功能,ProvidePlugin都无法正常运行。
imports-loader 覆写this指向.
npm i imports-loader
在CommonJS环境下,this指向module.exports。通过imports-loader将this指向window.
function component() { var element = document.createElement('div'); element.innerHTML = join(['hello','webpack'],' '); + this.alert('test hahaha'); return element; } document.body.appendChild(component());
module: { rules: [ { test: require.resolve('./src/test.js'), use: 'imports-loader?this=>window' } ] },

exports-loader 将一个全局变量作为一个普通模块导出。
npm i exports-loader
global.js // 注意:这个文件中没有任何export语句。
const file = 'this is file text'; var helper = { parse: function() { console.log('this parse function comes from global.js'); } }
webpack.config.js
module: { rules: [ { test: require.resolve('./src/global.js'), use: 'exports-loader?file,parse=helper.parse' } ] },
运行webpack编译命令,然后在test.js中导入
import {file, parse} from './global'; function component() { var element = document.createElement('div'); element.innerHTML = join(['hello','webpack'],' '); console.log(file); parse(); return element; } document.body.appendChild(component());
再运行编译命令

polyfill 是一个用在浏览器 API 上的 shim。
我们通常的做法是先检查当前浏览器是否支持某个 API,如果不支持的话就加载对应的 polyfill。
npm install --save babel-polyfill
npm install --save whatwg-fetch
官网上,不推荐在主 bundle 中引入 polyfills,因为这不利于已具备这些模块功能的现代浏览器用户,会使他们下载体积很大、但却不需要的脚本文件。推荐做法是将其放入一个单独的文件。
// polyfill.js
import 'babel-polyfill';
import 'whatwg-fetch';
entry: { polyfills: './src/polyfills.js', index: './src/index.js' },
index.html
<!doctype html>
<html>
<head>
<title>Getting Started</title>
+ <script>
// 检测需要的功能是否支持
+ var modernBrowser = (
+ 'fetch' in window &&
+ 'assign' in Object
+ );
+ // 若不支持,则导入
+ if ( !modernBrowser ) {
+ var scriptElement = document.createElement('script');
+
+ scriptElement.async = false;
+ scriptElement.src = '/polyfills.bundle.js';
+ document.head.appendChild(scriptElement);
+ }
+ </script>
</head>
<body>
<script src="index.bundle.js"></script>
</body>
</html>
script-loader 会在全局上下文中对代码进行取值,类似于通过一个 script 标签引入脚本。在这种模式下,每一个标准的库(library)都应该能正常运行。require,module等取值为undefine.
当使用 script-loader 时,模块将转化为字符串,然后添加到 bundle 中。它不会被webpack 压缩,所以应该选择一个 min 版本。同时,script-loader将不会有devtool 的支持。
这些老旧的模块如果没有 AMD/CommonJS 规范版本,但你也想将他们加入 /dist 目录,你可以使用 noParse 来标识出这个模块。这样就能使 webpack 将引入这些模块,但是不进行转化(parse)和解析(resolve) require和 import 语句。这个实践将提升构建性能。
---------------------------------------------------------------------------------------
在构建中涉及性能的loaders
thread-loader
可以将非常消耗资源的 loaders 转存到 worker pool 中。
cache-loader 启用持久化缓存
可以在多个编译之间共享缓存。
使用 package.json 中的 "postinstall" 清除缓存目录。