目的
本文将会介绍下面几个部分的内容:
1,babel7 结合 webpack3 的用法
2,tree-shaking 对于普通 js 函数的影响
3,tree-shaking 对于 react 组件的影响
相关技术
这里我们将使用 babel7,也是目前最新的版本,你会看到不再需要 babel-preset-es2015 这些东西了.所有的 babel 插件都改成 @babel/xxx 的形式.
babel-loader 也必须使用 8 + 版本.
webpack 版本必须 3+.
react 和 react-dom 均采用 16+.
配置公共开发环境
"devDependencies": {
"@babel/core": "^7.0.0-beta.36",
"@babel/preset-env": "^7.0.0-beta.36",
"@babel/preset-react": "^7.0.0-beta.36",
"babel-loader": "^8.0.0-beta.0",
"uglifyjs-webpack-plugin": "^1.1.6",
"webpack": "^3.10.0"
},
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
}
安装好上面的插件之后,需要配置几个公共文件.
1,.babelrc
babel8 的写法是下面这种,需要注意了,别用以前的写法了.
很简单的配置,可以不关注
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
"env": {
"production": {
"presets": ["react-optimize"]
}
}
}
2,.eslint
webpack 配置了 2 个对象,打包后的 app.js 和 shaking.js 分别用来测试普通函数和 React 组件对于 tree-shaking 的支持.
{
"env": {
"browser": true,
"es6": true
},
"parserOptions": {
"sourceType": "module"
},
"rules": {
"keyword-spacing": 0,
"node/no-unsupported-features": 0
}
}
3,
webpack.config.js
主文件
const path = require('path');
const webpack = require('webpack');
//压缩js的插件
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
//入口文件和输出文件的路径
const PATHS = {
app: path.join(__dirname, 'app', 'entry'),
//react入口文件
build: path.join(__dirname, 'build'),
//输出文件
shaking: path.join(__dirname, 'app', 'shaking') //普通函数入口文件
};
module.exports = [
//react打包配置
{
entry: {
vendor: ['react', 'react-dom'],
app: PATHS.app,
},
output: {
path: path.join(PATHS.build),
filename: '[name].js',
},
plugins: [new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
}), new UglifyJSPlugin()],
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/
}]
}
},
//普通函数打包配置
{
entry: {
shaking: PATHS.shaking,
},
output: {
path: path.join(PATHS.build),
filename: '[name].js',
},
plugins: [new UglifyJSPlugin()]
}];
1,主文件位于 app 目录下面.
2,有 2 个入口文件,分别是 entry.js 和 shaking.js
react 组件顶层容器
//entry.js
import React from 'react'
import { ReactDOm } from 'react-dom'
import App from './App'
ReactDOM.render(
App,
document.getElementById('root')
);
//shaking.js
//这是来自webpack官方例子
import {
square
}
from './lib/utils.js';
function component() {
var element = document.createElement('pre');
element.innerhtml = ['Hello webpack!', '5 cubed is equal to ' + square(10)].join('\n\n');
return element;
}
document.body.appendChild(component());
3,App.js
4,components 文件夹
import React from 'react'
import A from './components/A'
const App = () => {
return <A />
}
export default App
react 子组件
return ( < div > 测试tree shaking的效果 {
import React from 'react'import {
square
}
from '../lib/utils'const A = () = >{
5,lib 文件夹
square(10)
} < /div>
)
}/
export 模块导出函数
打包测试 tree-shaking
export function square(x) {
return x * x;
}
export function cube(x) {
return x * x * x;
}
1,普通函数打包结果
下面的代码你前面全都可以忽略,只需要看函数的末尾,可以看到函数最末尾只打包了 square 方法,没有使用到的 cube 方法成功被干掉了,这说明 tree-shaking 生效.
2,react 组件打包结果
!
function(e) {
var n = {};
function t(r) {
if (n[r]) return n[r].exports;
var o = n[r] = {
i: r,
l: !1,
exports: {}
};
return e[r].call(o.exports, o, o.exports, t),
o.l = !0,
o.exports
}
t.m = e,
t.c = n,
t.d = function(e, n, r) {
t.o(e, n) || Object.defineProperty(e, n, {
configurable: !1,
enumerable: !0,
get: r
})
},
t.n = function(e) {
var n = e && e.__esModule ?
function() {
return e.
default
}:
function() {
return e
};
return t.d(n, "a", n),
n
},
t.o = function(e, n) {
return Object.prototype.hasOwnProperty.call(e, n)
},
t.p = "",
t(t.s = 0)
} ([function(e, n, t) {
"use strict";
Object.defineProperty(n, "__esModule", {
value: !0
});
var r, o = t(1);
document.body.appendChild(((r = document.createElement("pre")).innerHTML = ["Hello webpack!", "5 cubed is equal to " + Object(o.a)(10)].join("\n\n"), r))
},
function(e, n, t) {
"use strict";
//只打包了square
n.a = function(e) {
return e * e
}
}]);
同样,你只需要看函数的最末尾,发现 square 和 cube 都打包进来,tree-shaking 没有生效.
这是为什么呢?我想可能和使用了 babel-loader 有关,而 webpack 官方的 demo 也没有对 react 组件的 tree-shaking 做说明,所以我暂时认为它还存在一定的缺陷.让我们期待 webpack4,看它能不能更好的解决大部分 js 的 tree-shaking 功能.
源码
webpackJsonp([0], {
27: function(e, t, u) {
"use strict";
r(u(2)),
u(8);
var n = r(u(28));
function r(e) {
return e && e.__esModule ? e : {
default: e
}
}
ReactDOM.render(n.default, document.getElementById("root"))
},
28: function(e, t, u) {
"use strict";
Object.defineProperty(t, "__esModule", {
value: !0
}),
t.default = void 0;
var n, r = (n = u(2)) && n.__esModule ? n : {
default: n
}, o = u(29);
var c = function() {
return r.default.createElement("div", null, (0,
o.square)(10))
};
t.default = c
},
29: function(e, t, u) {
"use strict";
Object.defineProperty(t, "__esModule", {
value: !0
}),
//打包了square
t.square = function(e) {
return e * e
}
,
//打包了cube
t.cube = function(e) {
return e * e * e
}
}
}, [27]);
前往 github 查看: webpack-tree-shaking
7 小时前发布
来源: https://segmentfault.com/a/1190000012747905