ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
参考:[前端工具链课(二)—— 模块化工具及组件化思想](http://www.toutiao.com/a6357876639150096642/) [做了一夜动画,让大家十分钟搞懂 Webpack](https://mp.weixin.qq.com/s/i6_fIcLDeDFmvZJj8NYrVg) **entry.js** ```javascript var foo = require('./foo.js'); // require('./style.css'); console.log(foo.bar); ``` **foo.js** ```javascript module.exports = { bar: 5555 } ``` **webpack.config.js** ```javascript module.exports = { entry: './entry.js', // 入口文件 output: { path: './build', filename: 'output.js' // 输出文件路径及文件名 }, module: { loaders: [ { test: /\.css$/, loader: 'style!css' } // `!` 是管道,loader 会从后往前依次执行 ] } } ``` **执行** ```shell webpack ``` **生成 ./build/output.js** ``` (function(modules) { // webpackBootstrap // The module cache var installedModules = {}; // The require function function __webpack_require__(moduleId) { // Check if module is in cache if(installedModules[moduleId]) return installedModules[moduleId].exports; // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { exports: {}, id: moduleId, loaded: false }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.loaded = true; // Return the exports of the module return module.exports; } // expose the modules object (__webpack_modules__) __webpack_require__.m = modules; // expose the module cache __webpack_require__.c = installedModules; // __webpack_public_path__ __webpack_require__.p = ""; // Load entry module and return exports return __webpack_require__(0); }) /************************************************************************/ ([ /* 0 */ function(module, exports, __webpack_require__) { var foo = __webpack_require__(1); // require('./style.css'); console.log(foo.bar); }, /* 1 */ function(module, exports) { module.exports = { bar: 5555 } } ]); ``` 在控制台执行`output.js`,输出了`5555`。 * * * * * 以上是一个最简单,最基本的由 `webpack` 将 `node CommonJS` 代码转化为浏览器端执行代码的过程。 ### 下面来分析 首先我们应该首先注意到,上面代码 ~~~ /************************************************************************/ ~~~ 将两段代码分割开了,实际上是这样的结构: ~~~ (function(){})() ~~~ 所以这就是一个匿名函数的自调用结构了。 ……有时间详细分析吧,其实很简单…… 参考: - [如何理解和熟练运用js中的call及apply?](https://www.zhihu.com/question/20289071) - [javascript里function之前加上感叹号 ' ! ' 会怎么样?](https://segmentfault.com/q/1010000000117476) - [function与感叹号](https://swordair.com/function-and-exclamation-mark/) * * * * * ### 其他 ~~~javascript (function(globalObj){ if(typeof module === 'object' && typeof module.exports === 'object'){ module.exports = globalObj; }else{ if(window.salt){ window.salt['router'] = globalObj; }else{ window.salt = { router:globalObj } } } })(Salt_router) ~~~ >[danger] 注意这段js代码可以在浏览器环境和`NodeJS`环境中运行哦。(node环境下webpack打包时会导出模块,而在浏览器上运行时,会暴露出全局变量) ### 扩展 html head里面的加载器: ~~~html <head> …… <!-- head里面的"加载器"还不能获取到head对象,但可以获取到script,利用这个特性也能实现加载(如果是head之后的,那么可以使用document.head) --> <script> var PUBLIC_URL = 'http://niceui.cn/public'; var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?cb41502e6f72ba22487a33d4a5d7f9df"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> …… </head> ~~~ update:2017-3-7 13:49:55