webpack 打包时到底如何组织js
问题一:引入前端库,方法也是不一样的
比如 lodash.js ,作为一个 chunk 用 html-webpack-plugin 打包到页面里,会生成一个全局变量 window._ ,在其它 js 中不必 require('lodash'); 就可以直接使用 window._
比如 webpack-zepto,作为一个 chunk 用 html-webpack-plugin 打包到页面里,不会生成 window.$ ,如果在其它 js 中直接使用 window.$ ,就会报错。需要在其它 js 中 var $ = require('webpack-zepto'); 这样 zepto 和页面 js 会打包到一个文件里,体积太大,而且不利于浏览器缓存
为了有效利用浏览器缓存,避免单个 js 体积太大,我们希望每个前端库打包成一个 js ,和页面逻辑分开
问题二:CommonsChunkPlugin
针对上一个问题,大家会提出使用 CommonsChunkPlugin ,参考这里
然而,使用 CommonsChunkPlugin 后,被指定的公共文件成了 js 的入口,其它 js 包括其它前端库都依赖这个 js ,如:
entry : { 'lodash' : ['lodash'], 'zepto' : ['webpack-zepto'], }, plugins : [ new CommonsChunkPlugin({ names : ['zepto', 'lodash'] }), ... ]
打包后的 zepto.js
/******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window["webpackJsonp"]; /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {
打包后的 lodash.js
webpackJsonp([2],{ /***/ 0: /***/ function(module, exports, __webpack_require__) {
那么必须指定 zepto.js 放在 lodash.js 的前面,不然就会报 webpackJsonp 未定义的错误!
然而原本 zepto 和 lodash 是没有相互依赖的关系的,能忍?
还有更不能妥协的场景,我要引入一个 jsA,它原本没有任何依赖,但它必须放在 head 里,因为它加载时会执行 document.write
打包时,我可以指定 jsA 放在 head 里,然而现在它依赖于 zepto 了,就必须把 zepto + jsA 放在 head 里
目前的解决方案:
不使用 CommonsChunkPlugin,每一个前端库,新建一个 js 专门 require 它,并生成一个全局变量,如:
lib/_zepto.js
window.$ = require("webpack-zepto");
然后作为一个 chunk 打包到页面中
这样解决了以上两个问题:
1. 每个前端库打包成一个独立 js,可以有效利用浏览器缓存,生成全局变量,页面 js 中可以直接使用
2. 不相互依赖的前端库位置随意,只要确保它们都在页面逻辑 js 前引入就可以了
抛砖引玉,请高手批评指正!谢谢!