本文着重介绍import、require混用的状况下打包结果有何不一样,以及webpack打包出的js运行机制。webpack负责将commonjs和es6模块转化为浏览器认识的语句。javascript
{
"presets": [
["es2015", {"modules": false}],
"stage-2"
]
}
复制代码
app.js(entry):html
import c from './c';
import {c1,c2} from './c'
console.log(c,c1,c2)
export default '我是a';
复制代码
c.jsjava
import b from './b'
export let c1 = '我是c111'
export let c2 = '我是c222'
export default '我是c';
复制代码
b.jswebpack
export default 'bbb';
复制代码
htmlgit
<script src='./app.js'></script>
<script type="text/javascript">
console.log(app)
</script>
复制代码
此种状况app.js、b.js、c.js都是es6模块。es6
html控制台输出github
我是c 我是c111 我是c222
{default: "我是a", __esModule: true}
复制代码
打包出的app.js以下:web
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__c__ = __webpack_require__(2);
console.log(__WEBPACK_IMPORTED_MODULE_0__c__["c" /* default */], __WEBPACK_IMPORTED_MODULE_0__c__["a" /* c1 */], __WEBPACK_IMPORTED_MODULE_0__c__["b" /* c2 */]);
/* harmony default export */ __webpack_exports__["default"] = ('我是a');
复制代码
app暴露出的是一个对象,而且增长了default和__esModule属性。浏览器
c.js以下bash
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return c1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return c2; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__b__ = __webpack_require__(4);
var c1 = '我是c111';
var c2 = '我是c222';
/* harmony default export */ __webpack_exports__["c"] = ('我是c');
复制代码
c.js暴露了三个属性。而且c将export default转化为了"c"属性,而后会经过调用__WEBPACK_IMPORTED_MODULE_0__c__["c"]来获取c的default值。
b.js
/* unused harmony default export */ var _unused_webpack_default_export = ('bbb');
复制代码
因为b.js虽然被c.js import了,可是没有使用,因此b.js并无export出去。压缩模式下b.js会被删除。这就是webpack tree-shaking功能
若是入口模块是es6模块,并且引用的模块也是es6模块,那么引用编译后不会添加{__esModule:true},只有入口模块才会添加{__esModule:true},若是入口模块有export default的值,那么default会转化为暴露对象的default属性。
将案例一的c.js改成:
let c1 = 'c1'
let c2 = 'c2'
module.exports = {
c1,
c2,
}
复制代码
此种状况app.js、b.js是es6模块,c.js是commonjs模块
c.js以下:
var c1 = 'c1';
var c2 = 'c2';
module.exports = {
c1: c1,
c2: c2
};
复制代码
若是入口模块是es6模块,引入的模块是commonjs模块,那么引入的模块会原样输出,而且引入的模块将不会有default属性。
将案例一的b.js改成:
module.exports = 'bbb'
复制代码
此种状况app.js、c.js是es6模块,b.js是commonjs模块,但b只是import了并未使用
b.js以下:
module.exports = 'bbb'
复制代码
若是入口模块是es6模块,引入的模块是commonjs模块但并未使用,那么webpack的tree-shaking功能不会生效,将打包的js压缩后仍是会存在b.js
复制代码
将案例一的app.js改成:
var b = require('./b')
var c = require('./c')
console.log(b.default)
console.log(c)
module.exports = {
a:'我是a'
}
复制代码
此种状况b.js、c.js是es6模块,app.js是commonjs模块
app.js以下:
var b = __webpack_require__(3);
var c = __webpack_require__(0);
console.log(b.default);
console.log(c);
module.exports = {
a: '我是a'
}
复制代码
b.js以下
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony default export */ __webpack_exports__["default"] = ('bbb');
复制代码
若是入口模块是commonjs模块,引入的模块是es6模块,那么es6模块编译后会添加{__esModule:true}。若是被调用的es6模块中刚好有export default语句,那么编译后的es6模块将会添加.default = ...。这时候若是入口commonjs模块想调用es6模块的default值,就须要手动添加b.default。例如:var b = require('./b').default console.log(b)。另:commonjs模块中不能使用import语句,会报错!
模块所有原样输出。没有export default的状况了。
es6模块调用commonjs模块,能够直接使用commonjs模块,commonjs模块将不会被webpack的模块系统编译而是会原样输出,而且commonjs模块没有.default属性
es6模块调用es6模块,被调用的es6模块不会添加{__esModule:true},只有调用者才会添加{__esModule:true};而且能够进行tree-shaking操做,若是被调用的es6模块只是import进来,可是并无被用到,那么被调用的es6模块将会被标记为/* unused harmony default export */,在压缩时此模块将会被删除(例外:若是被调用的es6模块里有当即执行语句,那么这些语句将会被保留)。
若是是commonjs模块引用了es6模块,那么es6模块编译后会添加{__esModule:true}。若是被调用的es6模块中刚好有export default语句,那么编译后的es6模块将会添加.default = ...,这时调用require进来的es6模块默认值,就须要例如:var b = require('./b').default console.log(b)
若是commonjs模块调用commonjs模块,那么commonjs模块会原样输出。
commonjs模块中不能使用import语句,会报错
webpakc的output设置会设置模块的打包格式和保留变量,若是设置library = 'test',那么打包后的js执行完成后全部的模块将会挂到window.test上