Repository: TooBug/webpack-guide Branch: master Commit: 580e7494307c Files: 138 Total size: 150.1 KB Directory structure: gitextract_rpn91ran/ ├── .coding-ide/ │ └── settings.json ├── .gitignore ├── LANGS.md ├── README.md ├── examples/ │ ├── chapter2/ │ │ ├── amd/ │ │ │ ├── bundle1.1.js │ │ │ ├── bundle2.1.js │ │ │ ├── example1.1.html │ │ │ ├── example1.1.js │ │ │ ├── example2.1.html │ │ │ ├── example2.1.js │ │ │ └── example2.2.js │ │ ├── commonjs/ │ │ │ ├── bundle1.1.js │ │ │ ├── example1.1.html │ │ │ ├── example1.1.js │ │ │ └── example1.2.js │ │ ├── node-modules-and-npm/ │ │ │ ├── example1/ │ │ │ │ ├── bundle1.1.js │ │ │ │ ├── example1.1.html │ │ │ │ ├── example1.1.js │ │ │ │ └── package.json │ │ │ └── example2/ │ │ │ ├── bundle2.1.js │ │ │ ├── example2.1.html │ │ │ ├── example2.1.js │ │ │ └── package.json │ │ ├── non-moduler/ │ │ │ ├── bundle1.1.js │ │ │ ├── example1.1.html │ │ │ └── example1.1.js │ │ └── umd/ │ │ ├── bundle1.1.js │ │ ├── bundle1.2.js │ │ ├── example1.1.js │ │ └── package.json │ ├── chapter3/ │ │ ├── chunks/ │ │ │ ├── example1/ │ │ │ │ ├── 1.bundle.js │ │ │ │ ├── 2.bundle.js │ │ │ │ ├── a.js │ │ │ │ ├── b.js │ │ │ │ ├── bundle.js │ │ │ │ ├── c.js │ │ │ │ ├── index.html │ │ │ │ └── main.js │ │ │ └── example2/ │ │ │ ├── 1.bundle.1.js │ │ │ ├── 2.bundle.2.js │ │ │ ├── a.js │ │ │ ├── b.js │ │ │ ├── bundle.main1.js │ │ │ ├── bundle.main2.js │ │ │ ├── c.js │ │ │ ├── index.html │ │ │ ├── main.2.js │ │ │ ├── main.js │ │ │ └── webpack.config.js │ │ ├── common-chunks-plugin/ │ │ │ ├── example1/ │ │ │ │ ├── a.js │ │ │ │ ├── b.js │ │ │ │ ├── bundle.main1.js │ │ │ │ ├── bundle.main2.js │ │ │ │ ├── c.js │ │ │ │ ├── index.html │ │ │ │ ├── main.2.js │ │ │ │ ├── main.js │ │ │ │ └── webpack.config.js │ │ │ ├── example2/ │ │ │ │ ├── a.js │ │ │ │ ├── b.js │ │ │ │ ├── bundle.main1.js │ │ │ │ ├── bundle.main2.js │ │ │ │ ├── c.js │ │ │ │ ├── common.js │ │ │ │ ├── index.html │ │ │ │ ├── main.2.js │ │ │ │ ├── main.js │ │ │ │ ├── package.json │ │ │ │ └── webpack.config.js │ │ │ └── example3/ │ │ │ ├── a.js │ │ │ ├── b.js │ │ │ ├── bundle.main1.js │ │ │ ├── bundle.main2.js │ │ │ ├── c.js │ │ │ ├── index.html │ │ │ ├── main.2.js │ │ │ ├── main.js │ │ │ ├── package.json │ │ │ └── webpack.config.js │ │ └── config/ │ │ ├── example1/ │ │ │ ├── bundle1.1.js │ │ │ ├── example1.1.js │ │ │ └── webpack.config.js │ │ ├── example2/ │ │ │ ├── 00a87887166c6302d5c5.js │ │ │ ├── example2.1.js │ │ │ ├── example2.2.js │ │ │ ├── main.js │ │ │ └── webpack.config.js │ │ ├── example3/ │ │ │ ├── example3.1-6f17d6321f8580500bc9.js │ │ │ ├── example3.1-ef6b40ba3b9335fc2551.js │ │ │ ├── example3.1.js │ │ │ ├── example3.2-6f17d6321f8580500bc9.js │ │ │ ├── example3.2-b92fc07f9784897342c5.js │ │ │ ├── example3.2.js │ │ │ ├── main-d4f0fb1b36bb83969e77.js │ │ │ └── webpack.config.js │ │ └── example4/ │ │ ├── dist/ │ │ │ ├── example4.1.js │ │ │ └── hello/ │ │ │ └── example4.2.js │ │ ├── src/ │ │ │ ├── example4.1.js │ │ │ └── hello/ │ │ │ └── example4.2.js │ │ └── webpack.config.js │ └── chapter4/ │ ├── exports-loader/ │ │ └── example1/ │ │ ├── bundle1.js │ │ ├── bundle2.js │ │ ├── example1.1.js │ │ ├── example1.2.js │ │ ├── index.html │ │ ├── package.json │ │ └── webpack.config.js │ └── using-loaders/ │ └── example1/ │ ├── bundle.js │ ├── example1.1.js │ ├── example1.2.coffee │ ├── index.html │ └── package.json ├── notes └── zh-cn/ ├── README.md ├── SUMMARY.md ├── chapter1/ │ ├── README.md │ ├── ancient-times.md │ ├── modular-age.md │ └── name-spacing-age.md ├── chapter2/ │ ├── README.md │ ├── amd.md │ ├── commonjs.md │ ├── entry-point.md │ ├── node-modules-and-npm.md │ ├── non-moduler.md │ └── umd.md ├── chapter3/ │ ├── README.md │ ├── advanced-config.md │ ├── chunks.md │ ├── cli-api.md │ ├── common-chunks-plugin.md │ └── config.md ├── chapter4/ │ ├── bundle-loader.md │ ├── exports-loader.md │ ├── expose-loader.md │ ├── imports-loader.md │ └── using-loaders.md └── chapter6/ └── ts-and-vue.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .coding-ide/settings.json ================================================ {} ================================================ FILE: .gitignore ================================================ node_modules webpack.sublime-project webpack.sublime-workspace .history ================================================ FILE: LANGS.md ================================================ * [简体中文](zh-cn/) ================================================ FILE: README.md ================================================ # webpack指南 本指南由TooBug根据自己的理解和使用经验编写,初衷是为了方便国内的前端开发者更好地接触和使用webpack这个强大的前端打包工具。 初次提交诞生于2015年10月20日,彼时webpack还是1.x,国内中文文档相当少,而官方英文文档也语焉不详,饱受诟病,故诞生此指南。 然而由于个人精力方面的原因,本指南未能如期完成。时下webpack的资料已经遍地开花,随着webpack 2的发布,一方面官方文档也趋于完善,另一方面很多配置和用法已不再兼容,因此本指南的部分内容可能存在不准确的情况,请读者自行鉴别。 另外,本指南有可能长期弃坑…… ================================================ FILE: examples/chapter2/amd/bundle1.1.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 __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ ], __WEBPACK_AMD_DEFINE_RESULT__ = function(){ alert('hello world!'); }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/amd/bundle2.1.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 __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1) ], __WEBPACK_AMD_DEFINE_RESULT__ = function(example2){ example2.sayHello(); }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ ], __WEBPACK_AMD_DEFINE_RESULT__ = function(){ return { sayHello:function(){ alert('hello world!'); } }; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/amd/example1.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/amd/example1.1.js ================================================ define([ ],function(){ alert('hello world!'); }); ================================================ FILE: examples/chapter2/amd/example2.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/amd/example2.1.js ================================================ define([ './example2.2' ],function(example2){ example2.sayHello(); }); ================================================ FILE: examples/chapter2/amd/example2.2.js ================================================ define([ ],function(){ return { sayHello:function(){ alert('hello world!'); } }; }); ================================================ FILE: examples/chapter2/commonjs/bundle1.1.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 example2 = __webpack_require__(1); example2.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { var me = { sayHello:function(){ alert('hello world!'); } }; module.exports = me; /***/ } /******/ ]); ================================================ FILE: examples/chapter2/commonjs/example1.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/commonjs/example1.1.js ================================================ var example2 = require('./example1.2'); example2.sayHello(); ================================================ FILE: examples/chapter2/commonjs/example1.2.js ================================================ var me = { sayHello:function(){ alert('hello world!'); } }; module.exports = me; ================================================ FILE: examples/chapter2/node-modules-and-npm/example1/bundle1.1.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 url = __webpack_require__(1); var result = url.parse('http://webpack.toobug.net/zh-cn/index.html'); console.log(result); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var punycode = __webpack_require__(2); exports.parse = urlParse; exports.resolve = urlResolve; exports.resolveObject = urlResolveObject; exports.format = urlFormat; exports.Url = Url; function Url() { this.protocol = null; this.slashes = null; this.auth = null; this.host = null; this.port = null; this.hostname = null; this.hash = null; this.search = null; this.query = null; this.pathname = null; this.path = null; this.href = null; } // Reference: RFC 3986, RFC 1808, RFC 2396 // define these here so at least they only have to be // compiled once on the first module load. var protocolPattern = /^([a-z0-9.+-]+:)/i, portPattern = /:[0-9]*$/, // RFC 2396: characters reserved for delimiting URLs. // We actually just auto-escape these. delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], // RFC 2396: characters not allowed for various reasons. unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), // Allowed by RFCs, but cause of XSS attacks. Always escape these. autoEscape = ['\''].concat(unwise), // Characters that are never ever allowed in a hostname. // Note that any invalid chars are also handled, but these // are the ones that are *expected* to be seen, so we fast-path // them. nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), hostEndingChars = ['/', '?', '#'], hostnameMaxLen = 255, hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, // protocols that can allow "unsafe" and "unwise" chars. unsafeProtocol = { 'javascript': true, 'javascript:': true }, // protocols that never have a hostname. hostlessProtocol = { 'javascript': true, 'javascript:': true }, // protocols that always contain a // bit. slashedProtocol = { 'http': true, 'https': true, 'ftp': true, 'gopher': true, 'file': true, 'http:': true, 'https:': true, 'ftp:': true, 'gopher:': true, 'file:': true }, querystring = __webpack_require__(4); function urlParse(url, parseQueryString, slashesDenoteHost) { if (url && isObject(url) && url instanceof Url) return url; var u = new Url; u.parse(url, parseQueryString, slashesDenoteHost); return u; } Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { if (!isString(url)) { throw new TypeError("Parameter 'url' must be a string, not " + typeof url); } var rest = url; // trim before proceeding. // This is to support parse stuff like " http://foo.com \n" rest = rest.trim(); var proto = protocolPattern.exec(rest); if (proto) { proto = proto[0]; var lowerProto = proto.toLowerCase(); this.protocol = lowerProto; rest = rest.substr(proto.length); } // figure out if it's got a host // user@server is *always* interpreted as a hostname, and url // resolution will treat //foo/bar as host=foo,path=bar because that's // how the browser resolves relative URLs. if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { var slashes = rest.substr(0, 2) === '//'; if (slashes && !(proto && hostlessProtocol[proto])) { rest = rest.substr(2); this.slashes = true; } } if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) { // there's a hostname. // the first instance of /, ?, ;, or # ends the host. // // If there is an @ in the hostname, then non-host chars *are* allowed // to the left of the last @ sign, unless some host-ending character // comes *before* the @-sign. // URLs are obnoxious. // // ex: // http://a@b@c/ => user:a@b host:c // http://a@b?@c => user:a host:c path:/?@c // v0.12 TODO(isaacs): This is not quite how Chrome does things. // Review our test case against browsers more comprehensively. // find the first instance of any hostEndingChars var hostEnd = -1; for (var i = 0; i < hostEndingChars.length; i++) { var hec = rest.indexOf(hostEndingChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // at this point, either we have an explicit point where the // auth portion cannot go past, or the last @ char is the decider. var auth, atSign; if (hostEnd === -1) { // atSign can be anywhere. atSign = rest.lastIndexOf('@'); } else { // atSign must be in auth portion. // http://a@b/c@d => host:b auth:a path:/c@d atSign = rest.lastIndexOf('@', hostEnd); } // Now we have a portion which is definitely the auth. // Pull that off. if (atSign !== -1) { auth = rest.slice(0, atSign); rest = rest.slice(atSign + 1); this.auth = decodeURIComponent(auth); } // the host is the remaining to the left of the first non-host char hostEnd = -1; for (var i = 0; i < nonHostChars.length; i++) { var hec = rest.indexOf(nonHostChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // if we still have not hit it, then the entire thing is a host. if (hostEnd === -1) hostEnd = rest.length; this.host = rest.slice(0, hostEnd); rest = rest.slice(hostEnd); // pull out port. this.parseHost(); // we've indicated that there is a hostname, // so even if it's empty, it has to be present. this.hostname = this.hostname || ''; // if hostname begins with [ and ends with ] // assume that it's an IPv6 address. var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; // validate a little. if (!ipv6Hostname) { var hostparts = this.hostname.split(/\./); for (var i = 0, l = hostparts.length; i < l; i++) { var part = hostparts[i]; if (!part) continue; if (!part.match(hostnamePartPattern)) { var newpart = ''; for (var j = 0, k = part.length; j < k; j++) { if (part.charCodeAt(j) > 127) { // we replace non-ASCII char with a temporary placeholder // we need this to make sure size of hostname is not // broken by replacing non-ASCII by nothing newpart += 'x'; } else { newpart += part[j]; } } // we test again with ASCII char only if (!newpart.match(hostnamePartPattern)) { var validParts = hostparts.slice(0, i); var notHost = hostparts.slice(i + 1); var bit = part.match(hostnamePartStart); if (bit) { validParts.push(bit[1]); notHost.unshift(bit[2]); } if (notHost.length) { rest = '/' + notHost.join('.') + rest; } this.hostname = validParts.join('.'); break; } } } } if (this.hostname.length > hostnameMaxLen) { this.hostname = ''; } else { // hostnames are always lower case. this.hostname = this.hostname.toLowerCase(); } if (!ipv6Hostname) { // IDNA Support: Returns a puny coded representation of "domain". // It only converts the part of the domain name that // has non ASCII characters. I.e. it dosent matter if // you call it with a domain that already is in ASCII. var domainArray = this.hostname.split('.'); var newOut = []; for (var i = 0; i < domainArray.length; ++i) { var s = domainArray[i]; newOut.push(s.match(/[^A-Za-z0-9_-]/) ? 'xn--' + punycode.encode(s) : s); } this.hostname = newOut.join('.'); } var p = this.port ? ':' + this.port : ''; var h = this.hostname || ''; this.host = h + p; this.href += this.host; // strip [ and ] from the hostname // the host field still retains them, though if (ipv6Hostname) { this.hostname = this.hostname.substr(1, this.hostname.length - 2); if (rest[0] !== '/') { rest = '/' + rest; } } } // now rest is set to the post-host stuff. // chop off any delim chars. if (!unsafeProtocol[lowerProto]) { // First, make 100% sure that any "autoEscape" chars get // escaped, even if encodeURIComponent doesn't think they // need to be. for (var i = 0, l = autoEscape.length; i < l; i++) { var ae = autoEscape[i]; var esc = encodeURIComponent(ae); if (esc === ae) { esc = escape(ae); } rest = rest.split(ae).join(esc); } } // chop off from the tail first. var hash = rest.indexOf('#'); if (hash !== -1) { // got a fragment string. this.hash = rest.substr(hash); rest = rest.slice(0, hash); } var qm = rest.indexOf('?'); if (qm !== -1) { this.search = rest.substr(qm); this.query = rest.substr(qm + 1); if (parseQueryString) { this.query = querystring.parse(this.query); } rest = rest.slice(0, qm); } else if (parseQueryString) { // no query string, but parseQueryString still requested this.search = ''; this.query = {}; } if (rest) this.pathname = rest; if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { this.pathname = '/'; } //to support http.request if (this.pathname || this.search) { var p = this.pathname || ''; var s = this.search || ''; this.path = p + s; } // finally, reconstruct the href based on what has been validated. this.href = this.format(); return this; }; // format a parsed object into a url string function urlFormat(obj) { // ensure it's an object, and not a string url. // If it's an obj, this is a no-op. // this way, you can call url_format() on strings // to clean up potentially wonky urls. if (isString(obj)) obj = urlParse(obj); if (!(obj instanceof Url)) return Url.prototype.format.call(obj); return obj.format(); } Url.prototype.format = function() { var auth = this.auth || ''; if (auth) { auth = encodeURIComponent(auth); auth = auth.replace(/%3A/i, ':'); auth += '@'; } var protocol = this.protocol || '', pathname = this.pathname || '', hash = this.hash || '', host = false, query = ''; if (this.host) { host = auth + this.host; } else if (this.hostname) { host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); if (this.port) { host += ':' + this.port; } } if (this.query && isObject(this.query) && Object.keys(this.query).length) { query = querystring.stringify(this.query); } var search = this.search || (query && ('?' + query)) || ''; if (protocol && protocol.substr(-1) !== ':') protocol += ':'; // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. // unless they had them to begin with. if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { host = '//' + (host || ''); if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; } else if (!host) { host = ''; } if (hash && hash.charAt(0) !== '#') hash = '#' + hash; if (search && search.charAt(0) !== '?') search = '?' + search; pathname = pathname.replace(/[?#]/g, function(match) { return encodeURIComponent(match); }); search = search.replace('#', '%23'); return protocol + host + pathname + search + hash; }; function urlResolve(source, relative) { return urlParse(source, false, true).resolve(relative); } Url.prototype.resolve = function(relative) { return this.resolveObject(urlParse(relative, false, true)).format(); }; function urlResolveObject(source, relative) { if (!source) return relative; return urlParse(source, false, true).resolveObject(relative); } Url.prototype.resolveObject = function(relative) { if (isString(relative)) { var rel = new Url(); rel.parse(relative, false, true); relative = rel; } var result = new Url(); Object.keys(this).forEach(function(k) { result[k] = this[k]; }, this); // hash is always overridden, no matter what. // even href="" will remove it. result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. if (relative.href === '') { result.href = result.format(); return result; } // hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // take everything except the protocol from relative Object.keys(relative).forEach(function(k) { if (k !== 'protocol') result[k] = relative[k]; }); //urlParse appends trailing / to urls like http://www.example.com if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { result.path = result.pathname = '/'; } result.href = result.format(); return result; } if (relative.protocol && relative.protocol !== result.protocol) { // if it's a known url protocol, then changing // the protocol does weird things // first, if it's not file:, then we MUST have a host, // and if there was a path // to begin with, then we MUST have a path. // if it is file:, then the host is dropped, // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol[relative.protocol]) { Object.keys(relative).forEach(function(k) { result[k] = relative[k]; }); result.href = result.format(); return result; } result.protocol = relative.protocol; if (!relative.host && !hostlessProtocol[relative.protocol]) { var relPath = (relative.pathname || '').split('/'); while (relPath.length && !(relative.host = relPath.shift())); if (!relative.host) relative.host = ''; if (!relative.hostname) relative.hostname = ''; if (relPath[0] !== '') relPath.unshift(''); if (relPath.length < 2) relPath.unshift(''); result.pathname = relPath.join('/'); } else { result.pathname = relative.pathname; } result.search = relative.search; result.query = relative.query; result.host = relative.host || ''; result.auth = relative.auth; result.hostname = relative.hostname || relative.host; result.port = relative.port; // to support http.request if (result.pathname || result.search) { var p = result.pathname || ''; var s = result.search || ''; result.path = p + s; } result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; } var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), isRelAbs = ( relative.host || relative.pathname && relative.pathname.charAt(0) === '/' ), mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)), removeAllDots = mustEndAbs, srcPath = result.pathname && result.pathname.split('/') || [], relPath = relative.pathname && relative.pathname.split('/') || [], psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative // links like ../.. should be able // to crawl up to the hostname, as well. This is strange. // result.protocol has already been set by now. // Later on, put the first path part into the host field. if (psychotic) { result.hostname = ''; result.port = null; if (result.host) { if (srcPath[0] === '') srcPath[0] = result.host; else srcPath.unshift(result.host); } result.host = ''; if (relative.protocol) { relative.hostname = null; relative.port = null; if (relative.host) { if (relPath[0] === '') relPath[0] = relative.host; else relPath.unshift(relative.host); } relative.host = null; } mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } if (isRelAbs) { // it's absolute. result.host = (relative.host || relative.host === '') ? relative.host : result.host; result.hostname = (relative.hostname || relative.hostname === '') ? relative.hostname : result.hostname; result.search = relative.search; result.query = relative.query; srcPath = relPath; // fall through to the dot-handling below. } else if (relPath.length) { // it's relative // throw away the existing file, and take the new path instead. if (!srcPath) srcPath = []; srcPath.pop(); srcPath = srcPath.concat(relPath); result.search = relative.search; result.query = relative.query; } else if (!isNullOrUndefined(relative.search)) { // just pull out the search. // like href='?foo'. // Put this after the other two cases because it simplifies the booleans if (psychotic) { result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host //this especialy happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } result.search = relative.search; result.query = relative.query; //to support http.request if (!isNull(result.pathname) || !isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.href = result.format(); return result; } if (!srcPath.length) { // no path at all. easy. // we've already handled the other stuff above. result.pathname = null; //to support http.request if (result.search) { result.path = '/' + result.search; } else { result.path = null; } result.href = result.format(); return result; } // if a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. var last = srcPath.slice(-1)[0]; var hasTrailingSlash = ( (result.host || relative.host) && (last === '.' || last === '..') || last === ''); // strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = srcPath.length; i >= 0; i--) { last = srcPath[i]; if (last == '.') { srcPath.splice(i, 1); } else if (last === '..') { srcPath.splice(i, 1); up++; } else if (up) { srcPath.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (!mustEndAbs && !removeAllDots) { for (; up--; up) { srcPath.unshift('..'); } } if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { srcPath.unshift(''); } if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { srcPath.push(''); } var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); // put the host back if (psychotic) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host //this especialy happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } mustEndAbs = mustEndAbs || (result.host && srcPath.length); if (mustEndAbs && !isAbsolute) { srcPath.unshift(''); } if (!srcPath.length) { result.pathname = null; result.path = null; } else { result.pathname = srcPath.join('/'); } //to support request.http if (!isNull(result.pathname) || !isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.auth = relative.auth || result.auth; result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; }; Url.prototype.parseHost = function() { var host = this.host; var port = portPattern.exec(host); if (port) { port = port[0]; if (port !== ':') { this.port = port.substr(1); } host = host.substr(0, host.length - port.length); } if (host) this.hostname = host; }; function isString(arg) { return typeof arg === "string"; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isNull(arg) { return arg === null; } function isNullOrUndefined(arg) { return arg == null; } /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */ ;(function(root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; var freeModule = typeof module == 'object' && module && !module.nodeType && module; var freeGlobal = typeof global == 'object' && global; if ( freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal ) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; var result = []; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function(value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * http://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ function toASCII(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.3.2', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( true ) { !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return punycode; }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (freeExports && freeModule) { if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } }(this)); /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)(module), (function() { return this; }()))) /***/ }, /* 3 */ /***/ function(module, exports) { module.exports = function(module) { if(!module.webpackPolyfill) { module.deprecate = function() {}; module.paths = []; // module.parent = undefined by default module.children = []; module.webpackPolyfill = 1; } return module; } /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.decode = exports.parse = __webpack_require__(5); exports.encode = exports.stringify = __webpack_require__(6); /***/ }, /* 5 */ /***/ function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } module.exports = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; var obj = {}; if (typeof qs !== 'string' || qs.length === 0) { return obj; } var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; if (options && typeof options.maxKeys === 'number') { maxKeys = options.maxKeys; } var len = qs.length; // maxKeys <= 0 means that we should not limit keys count if (maxKeys > 0 && len > maxKeys) { len = maxKeys; } for (var i = 0; i < len; ++i) { var x = qs[i].replace(regexp, '%20'), idx = x.indexOf(eq), kstr, vstr, k, v; if (idx >= 0) { kstr = x.substr(0, idx); vstr = x.substr(idx + 1); } else { kstr = x; vstr = ''; } k = decodeURIComponent(kstr); v = decodeURIComponent(vstr); if (!hasOwnProperty(obj, k)) { obj[k] = v; } else if (Array.isArray(obj[k])) { obj[k].push(v); } else { obj[k] = [obj[k], v]; } } return obj; }; /***/ }, /* 6 */ /***/ function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var stringifyPrimitive = function(v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; module.exports = function(obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return Object.keys(obj).map(function(k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (Array.isArray(obj[k])) { return obj[k].map(function(v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; /***/ } /******/ ]); ================================================ FILE: examples/chapter2/node-modules-and-npm/example1/example1.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/node-modules-and-npm/example1/example1.1.js ================================================ var url = require('url'); var result = url.parse('http://webpack.toobug.net/zh-cn/index.html'); console.log(result); ================================================ FILE: examples/chapter2/node-modules-and-npm/example1/package.json ================================================ { "name": "example1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } ================================================ FILE: examples/chapter2/node-modules-and-npm/example2/bundle2.1.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) { alert(typeof console); console.log('hello'); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/node-modules-and-npm/example2/example2.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/node-modules-and-npm/example2/example2.1.js ================================================ alert(typeof console); console.log('hello'); ================================================ FILE: examples/chapter2/node-modules-and-npm/example2/package.json ================================================ { "name": "example2", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } ================================================ FILE: examples/chapter2/non-moduler/bundle1.1.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) { alert('hello world'); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/non-moduler/example1.1.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter2/non-moduler/example1.1.js ================================================ alert('hello world'); ================================================ FILE: examples/chapter2/umd/bundle1.1.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 __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (root, factory) { if (true) { // AMD. Register as an anonymous module. !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { // Just return a value to define the module export. // This example returns an object, but the module // can return a function as the exported value. return {}; })); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/umd/bundle1.2.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) { /*** IMPORTS FROM imports-loader ***/ var define = false; (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { // Just return a value to define the module export. // This example returns an object, but the module // can return a function as the exported value. return {}; })); /***/ } /******/ ]); ================================================ FILE: examples/chapter2/umd/example1.1.js ================================================ (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { // Just return a value to define the module export. // This example returns an object, but the module // can return a function as the exported value. return {}; })); ================================================ FILE: examples/chapter2/umd/package.json ================================================ { "name": "umd", "version": "1.0.0", "description": "", "main": "bundle1.1.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "imports-loader": "^0.6.5" } } ================================================ FILE: examples/chapter3/chunks/example1/1.bundle.js ================================================ webpackJsonp([1],{ /***/ 2: /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ } }); ================================================ FILE: examples/chapter3/chunks/example1/2.bundle.js ================================================ webpackJsonp([2],{ /***/ 3: /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; /***/ } }); ================================================ FILE: examples/chapter3/chunks/example1/a.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; ================================================ FILE: examples/chapter3/chunks/example1/b.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; ================================================ FILE: examples/chapter3/chunks/example1/bundle.js ================================================ /******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window["webpackJsonp"]; /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0, callbacks = []; /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(installedChunks[chunkId]) /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); /******/ installedChunks[chunkId] = 0; /******/ } /******/ for(moduleId in moreModules) { /******/ modules[moduleId] = moreModules[moduleId]; /******/ } /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); /******/ while(callbacks.length) /******/ callbacks.shift().call(null, __webpack_require__); /******/ }; /******/ // The module cache /******/ var installedModules = {}; /******/ // object to store loaded and loading chunks /******/ // "0" means "already loaded" /******/ // Array means "loading", array contains callbacks /******/ var installedChunks = { /******/ 0:0 /******/ }; /******/ // 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; /******/ } /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { /******/ // "0" is the signal for "already loaded" /******/ if(installedChunks[chunkId] === 0) /******/ return callback.call(null, __webpack_require__); /******/ // an array means "currently loading". /******/ if(installedChunks[chunkId] !== undefined) { /******/ installedChunks[chunkId].push(callback); /******/ } else { /******/ // start chunk loading /******/ installedChunks[chunkId] = [callback]; /******/ var head = document.getElementsByTagName('head')[0]; /******/ var script = document.createElement('script'); /******/ script.type = 'text/javascript'; /******/ script.charset = 'utf-8'; /******/ script.async = true; /******/ script.src = __webpack_require__.p + "" + chunkId + ".bundle.js"; /******/ head.appendChild(script); /******/ } /******/ }; /******/ // 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 a=__webpack_require__(1); a.sayHello(); __webpack_require__.e/* nsure */(1, function(require){ var b = __webpack_require__(2); b.sayHello(); }); __webpack_require__.e/* require */(2, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(3)]; (function(c){ c.sayHello(); }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));}); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/chunks/example1/c.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; ================================================ FILE: examples/chapter3/chunks/example1/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter3/chunks/example1/main.js ================================================ var a=require('./a'); a.sayHello(); require.ensure(['./b'], function(require){ var b = require('./b'); b.sayHello(); }); require(['./c'], function(c){ c.sayHello(); }); ================================================ FILE: examples/chapter3/chunks/example2/1.bundle.1.js ================================================ webpackJsonp([1],{ /***/ 2: /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ } }); ================================================ FILE: examples/chapter3/chunks/example2/2.bundle.2.js ================================================ webpackJsonp([2],{ /***/ 3: /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; /***/ } }); ================================================ FILE: examples/chapter3/chunks/example2/a.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; ================================================ FILE: examples/chapter3/chunks/example2/b.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; ================================================ FILE: examples/chapter3/chunks/example2/bundle.main1.js ================================================ /******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window["webpackJsonp"]; /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0, callbacks = []; /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(installedChunks[chunkId]) /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); /******/ installedChunks[chunkId] = 0; /******/ } /******/ for(moduleId in moreModules) { /******/ modules[moduleId] = moreModules[moduleId]; /******/ } /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); /******/ while(callbacks.length) /******/ callbacks.shift().call(null, __webpack_require__); /******/ }; /******/ // The module cache /******/ var installedModules = {}; /******/ // object to store loaded and loading chunks /******/ // "0" means "already loaded" /******/ // Array means "loading", array contains callbacks /******/ var installedChunks = { /******/ 0:0 /******/ }; /******/ // 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; /******/ } /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { /******/ // "0" is the signal for "already loaded" /******/ if(installedChunks[chunkId] === 0) /******/ return callback.call(null, __webpack_require__); /******/ // an array means "currently loading". /******/ if(installedChunks[chunkId] !== undefined) { /******/ installedChunks[chunkId].push(callback); /******/ } else { /******/ // start chunk loading /******/ installedChunks[chunkId] = [callback]; /******/ var head = document.getElementsByTagName('head')[0]; /******/ var script = document.createElement('script'); /******/ script.type = 'text/javascript'; /******/ script.charset = 'utf-8'; /******/ script.async = true; /******/ script.src = __webpack_require__.p + "" + chunkId + ".bundle." + ({}[chunkId]||chunkId) + ".js"; /******/ head.appendChild(script); /******/ } /******/ }; /******/ // 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 a=__webpack_require__(1); a.sayHello(); __webpack_require__.e/* nsure */(1, function(require){ var b = __webpack_require__(2); b.sayHello(); }); __webpack_require__.e/* require */(2, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(3)]; (function(c){ c.sayHello(); }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));}); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/chunks/example2/bundle.main2.js ================================================ /******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window["webpackJsonp"]; /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0, callbacks = []; /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(installedChunks[chunkId]) /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); /******/ installedChunks[chunkId] = 0; /******/ } /******/ for(moduleId in moreModules) { /******/ modules[moduleId] = moreModules[moduleId]; /******/ } /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); /******/ while(callbacks.length) /******/ callbacks.shift().call(null, __webpack_require__); /******/ }; /******/ // The module cache /******/ var installedModules = {}; /******/ // object to store loaded and loading chunks /******/ // "0" means "already loaded" /******/ // Array means "loading", array contains callbacks /******/ var installedChunks = { /******/ 3:0 /******/ }; /******/ // 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; /******/ } /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { /******/ // "0" is the signal for "already loaded" /******/ if(installedChunks[chunkId] === 0) /******/ return callback.call(null, __webpack_require__); /******/ // an array means "currently loading". /******/ if(installedChunks[chunkId] !== undefined) { /******/ installedChunks[chunkId].push(callback); /******/ } else { /******/ // start chunk loading /******/ installedChunks[chunkId] = [callback]; /******/ var head = document.getElementsByTagName('head')[0]; /******/ var script = document.createElement('script'); /******/ script.type = 'text/javascript'; /******/ script.charset = 'utf-8'; /******/ script.async = true; /******/ script.src = __webpack_require__.p + "" + chunkId + ".bundle." + ({}[chunkId]||chunkId) + ".js"; /******/ head.appendChild(script); /******/ } /******/ }; /******/ // 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 a=__webpack_require__(1); a.sayHello(); __webpack_require__.e/* nsure */(1/* duplicate */, function(require){ var b = __webpack_require__(2); b.sayHello(); }); __webpack_require__.e/* require */(2/* duplicate */, function(__webpack_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(3)]; (function(c){ c.sayHello(); console.log('hello2'); }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));}); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/chunks/example2/c.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; ================================================ FILE: examples/chapter3/chunks/example2/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter3/chunks/example2/main.2.js ================================================ var a=require('./a'); a.sayHello(); require.ensure(['./b'], function(require){ var b = require('./b'); b.sayHello(); }); require(['./c'], function(c){ c.sayHello(); console.log('hello2'); }); ================================================ FILE: examples/chapter3/chunks/example2/main.js ================================================ var a=require('./a'); a.sayHello(); require.ensure(['./b'], function(require){ var b = require('./b'); b.sayHello(); }); require(['./c'], function(c){ c.sayHello(); }); ================================================ FILE: examples/chapter3/chunks/example2/webpack.config.js ================================================ module.exports = { entry:{ main1:'./main', main2:'./main.2' }, output:{ filename:'bundle.[name].js' } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/a.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/b.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/bundle.main1.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 a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); var c = __webpack_require__(3); c.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ }, /* 3 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/bundle.main2.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 a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/c.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/main.2.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/main.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); var c = require('./c'); c.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example1/webpack.config.js ================================================ module.exports = { entry:{ main1:'./main', main2:'./main.2' }, output:{ filename:'bundle.[name].js' } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/a.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/b.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/bundle.main1.js ================================================ webpackJsonp([0],[ /* 0 */ /***/ function(module, exports, __webpack_require__) { var a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); var c = __webpack_require__(3); c.sayHello(); /***/ }, /* 1 */, /* 2 */, /* 3 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; /***/ } ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/bundle.main2.js ================================================ webpackJsonp([1],[ /* 0 */ /***/ function(module, exports, __webpack_require__) { var a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); /***/ } ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/c.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/common.js ================================================ /******/ (function(modules) { // webpackBootstrap /******/ // install a JSONP callback for chunk loading /******/ var parentJsonpFunction = window["webpackJsonp"]; /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0, callbacks = []; /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(installedChunks[chunkId]) /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); /******/ installedChunks[chunkId] = 0; /******/ } /******/ for(moduleId in moreModules) { /******/ modules[moduleId] = moreModules[moduleId]; /******/ } /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); /******/ while(callbacks.length) /******/ callbacks.shift().call(null, __webpack_require__); /******/ if(moreModules[0]) { /******/ installedModules[0] = 0; /******/ return __webpack_require__(0); /******/ } /******/ }; /******/ // The module cache /******/ var installedModules = {}; /******/ // object to store loaded and loading chunks /******/ // "0" means "already loaded" /******/ // Array means "loading", array contains callbacks /******/ var installedChunks = { /******/ 2:0 /******/ }; /******/ // 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; /******/ } /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { /******/ // "0" is the signal for "already loaded" /******/ if(installedChunks[chunkId] === 0) /******/ return callback.call(null, __webpack_require__); /******/ // an array means "currently loading". /******/ if(installedChunks[chunkId] !== undefined) { /******/ installedChunks[chunkId].push(callback); /******/ } else { /******/ // start chunk loading /******/ installedChunks[chunkId] = [callback]; /******/ var head = document.getElementsByTagName('head')[0]; /******/ var script = document.createElement('script'); /******/ script.type = 'text/javascript'; /******/ script.charset = 'utf-8'; /******/ script.async = true; /******/ script.src = __webpack_require__.p + "" + chunkId + ".bundle." + ({"0":"main1","1":"main2"}[chunkId]||chunkId) + ".js"; /******/ head.appendChild(script); /******/ } /******/ }; /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ }) /************************************************************************/ /******/ ([ /* 0 */, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/main.2.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/main.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); var c = require('./c'); c.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/package.json ================================================ { "name": "example2", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "webpack": "^1.12.8" } } ================================================ FILE: examples/chapter3/common-chunks-plugin/example2/webpack.config.js ================================================ var webpack = require('webpack'); module.exports = { entry:{ main1:'./main', main2:'./main.2' }, output:{ filename:'bundle.[name].js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin('common.js', ['main1', 'main2']) ] }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/a.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/b.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/bundle.main1.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 a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); var c = __webpack_require__(3); c.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ }, /* 3 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/bundle.main2.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 a=__webpack_require__(1); a.sayHello(); var b = __webpack_require__(2); b.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m a!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ console.log('Hello World! I\'m b!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/c.js ================================================ module.exports = { sayHello:function(){ console.log('Hello World! I\'m c!'); } }; ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/main.2.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/main.js ================================================ var a=require('./a'); a.sayHello(); var b = require('./b'); b.sayHello(); var c = require('./c'); c.sayHello(); ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/package.json ================================================ { "name": "example2", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "webpack": "^1.12.8" } } ================================================ FILE: examples/chapter3/common-chunks-plugin/example3/webpack.config.js ================================================ var webpack = require('webpack'); module.exports = { entry:{ main1:'./main', main2:'./main.2' }, output:{ filename:'bundle.[name].js' }, /*plugins: [ new webpack.optimize.CommonsChunkPlugin({ name:'main1', chunks: ['main1', 'main2'], async:true })*/ ] }; ================================================ FILE: examples/chapter3/config/example1/bundle1.1.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) { module.exports = { sayHello:function(){ alert('Hello World!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example1/example1.1.js ================================================ module.exports = { sayHello:function(){ alert('Hello World!'); } }; ================================================ FILE: examples/chapter3/config/example1/webpack.config.js ================================================ module.exports = { entry:'./example1.1', output:{ filename:'bundle1.1.js' } }; ================================================ FILE: examples/chapter3/config/example2/00a87887166c6302d5c5.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__) { __webpack_require__(1); module.exports = __webpack_require__(2); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ alert('Hello World!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ alert('Hello World!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example2/example2.1.js ================================================ module.exports = { sayHello:function(){ alert('Hello World!'); } }; ================================================ FILE: examples/chapter3/config/example2/example2.2.js ================================================ module.exports = { sayHello:function(){ alert('Hello World!'); } }; ================================================ FILE: examples/chapter3/config/example2/main.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__) { __webpack_require__(1); module.exports = __webpack_require__(2); /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ alert('Hello World!'); } }; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = { sayHello:function(){ alert('Hello World!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example2/webpack.config.js ================================================ module.exports = { entry:['./example2.1','./example2.2'], output:{ //filename:'[name].js' filename:'[hash].js' //filename:'[chunkhash].js' } }; ================================================ FILE: examples/chapter3/config/example3/example3.1-6f17d6321f8580500bc9.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) { module.exports = { sayHello:function(){ alert('Hello World 3.1!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example3/example3.1-ef6b40ba3b9335fc2551.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) { module.exports = { sayHello:function(){ alert('Hello World 3.1!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example3/example3.1.js ================================================ module.exports = { sayHello:function(){ alert('Hello World 3.1!'); } }; ================================================ FILE: examples/chapter3/config/example3/example3.2-6f17d6321f8580500bc9.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) { module.exports = { sayHello:function(){ alert('Hello World 3.2!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example3/example3.2-b92fc07f9784897342c5.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) { module.exports = { sayHello:function(){ alert('Hello World 3.2!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example3/example3.2.js ================================================ module.exports = { sayHello:function(){ alert('Hello World 3.2!'); } }; ================================================ FILE: examples/chapter3/config/example3/main-d4f0fb1b36bb83969e77.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__) { (function webpackMissingModule() { throw new Error("Cannot find module \"./example2.1\""); }()); (function webpackMissingModule() { throw new Error("Cannot find module \"./example2.2\""); }()); /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example3/webpack.config.js ================================================ module.exports = { entry:{ 'example3.1':'./example3.1', 'example3.2':'./example3.2' }, output:{ //filename:'[name].js' //filename:'[name]-[hash].js' filename:'[name]-[chunkhash].js' } }; ================================================ FILE: examples/chapter3/config/example4/dist/example4.1.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) { module.exports = { sayHello:function(){ alert('Hello World 4.1!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example4/dist/hello/example4.2.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) { module.exports = { sayHello:function(){ alert('Hello World 4.3!'); } }; /***/ } /******/ ]); ================================================ FILE: examples/chapter3/config/example4/src/example4.1.js ================================================ module.exports = { sayHello:function(){ alert('Hello World 4.1!'); } }; ================================================ FILE: examples/chapter3/config/example4/src/hello/example4.2.js ================================================ module.exports = { sayHello:function(){ alert('Hello World 4.3!'); } }; ================================================ FILE: examples/chapter3/config/example4/webpack.config.js ================================================ module.exports = { entry:{ 'example4.1':'./src/example4.1', 'hello/example4.2':'./src/hello/example4.2' }, output:{ filename:'[name].js', path:'./dist' } }; ================================================ FILE: examples/chapter4/exports-loader/example1/bundle1.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 Hello = __webpack_require__(1); Hello(); /***/ }, /* 1 */ /***/ function(module, exports) { window.Hello = function(){ console.log('hello from global Hello function'); }; /***/ } /******/ ]); ================================================ FILE: examples/chapter4/exports-loader/example1/bundle2.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 Hello = __webpack_require__(1); Hello(); /***/ }, /* 1 */ /***/ function(module, exports) { window.Hello = function(){ console.log('hello from global Hello() function'); }; /*** EXPORTS FROM exports-loader ***/ module.exports = Hello; /***/ } /******/ ]); ================================================ FILE: examples/chapter4/exports-loader/example1/example1.1.js ================================================ var Hello = require('./example1.2'); Hello(); ================================================ FILE: examples/chapter4/exports-loader/example1/example1.2.js ================================================ window.Hello = function(){ console.log('hello from global Hello() function'); }; ================================================ FILE: examples/chapter4/exports-loader/example1/index.html ================================================ webpack.toobug.net ================================================ FILE: examples/chapter4/exports-loader/example1/package.json ================================================ { "name": "example1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "exports-loader": "^0.6.3" } } ================================================ FILE: examples/chapter4/exports-loader/example1/webpack.config.js ================================================ module.exports = { module:{ loaders:[ { test: require.resolve('./example1.2'), loader: "exports?Hello" } ] } }; ================================================ FILE: examples/chapter4/using-loaders/example1/bundle.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 hello = __webpack_require__(1); hello.sayHello(); /***/ }, /* 1 */ /***/ function(module, exports) { var Hello; Hello = (function() { function Hello(name) { this.name = name; } Hello.prototype.sayHello = function() { return alert("hello " + this.name); }; return Hello; })(); module.exports = new Hello('world'); /***/ } /******/ ]); ================================================ FILE: examples/chapter4/using-loaders/example1/example1.1.js ================================================ var hello = require('coffee!./example1.2.coffee'); hello.sayHello(); ================================================ FILE: examples/chapter4/using-loaders/example1/example1.2.coffee ================================================ class Hello constructor: (@name) -> sayHello: () -> alert "hello #{@name}" module.exports = new Hello 'world' ================================================ FILE: examples/chapter4/using-loaders/example1/index.html ================================================ webpack demo ================================================ FILE: examples/chapter4/using-loaders/example1/package.json ================================================ { "name": "example1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "coffee-loader": "^0.7.2", "coffee-script": "^1.10.0" } } ================================================ FILE: notes ================================================ http://stackoverflow.com/questions/28969861/managing-jquery-plugin-dependency-in-webpack http://alexomara.com/blog/webpack-and-jquery-include-only-the-parts-you-need/ 加载jquery及按需打包 http://jonathancreamer.com/advanced-webpack-part-1-the-commonschunk-plugin/ commonschunk插件 ================================================ FILE: zh-cn/README.md ================================================ # webpack指南 ## webpack webpack()是一个用于web项目的模块打包工具。在大部分的使用场景中,我们将它看作是一个web前端模块打包工具。 ![webpack](https://webpack.github.io/assets/what-is-webpack.png) 按照官方介绍,webpack可以将前端各种资源(包括CSS及其预编译方案、JS及其预编译方案)统一打包为`.js`文件和资源文件(图片)。 ## 关于本指南 本指南由TooBug编写,所有章节内容均按自己的理解编写,初衷是为了方便国内的前端开发者更好地接触和使用webpack这个强大的前端打包工具。 初次提交诞生于2015年10月20日,彼时webpack还是1.x,国内中文文档相当少,而官方英文文档也语焉不详,饱受诟病,故诞生此指南。 然而由于个人精力方面的原因,本指南未能如期完成。时下webpack的资料已经遍地开花,随着webpack 2的发布,一方面官方文档也趋于完善,另一方面很多配置和用法已不再兼容,因此本指南的部分内容可能存在不准确的情况,请读者自行鉴别。 另外,本指南有可能长期弃坑…… 联系方式: - 微博 [@TooBug](http://weibo.com/toooobug) - GitHub [@TooBug](https://github.com/TooBug) 本书Github地址,有任何意见和建议欢迎提出。 ================================================ FILE: zh-cn/SUMMARY.md ================================================ # webpack指南 * [第一章 模块化](chapter1/README.md) * [原始时代](chapter1/ancient-times.md) * [命名空间时代](chapter1/name-spacing-age.md) * [模块化时代](chapter1/modular-age.md) * [第二章 webpack入门](chapter2/README.md) * [入口文件](chapter2/entry-point.md) * [非模块化文件打包](chapter2/non-moduler.md) * [AMD模块打包](chapter2/amd.md) * [CommonJS模块打包](chapter2/commonjs.md) * [Node模块和NPM](chapter2/node-modules-and-npm.md) * [UMD模块打包](chapter2/umd.md) * [第三章 webpack进阶](chapter3/README.md) * [CLI与API使用模式](chapter3/cli-api.md) * [基本配置项](chapter3/config.md) * [分片](chapter3/chunks.md) * [CommonChunks插件](chapter3/common-chunks-plugin.md) * [SourceMap](chapter3/source-map.md) * [高级配置项](chapter3/advanced-config.md) * [第四章 Loader](chapter4/README.md) * [使用Loader](chapter4/using-loaders.md) * [常用Loader](chapter4/loader-list.md) * [bundle-loader](chapter4/bundle-loader.md) * [exports-loader](chapter4/exports-loader.md) * [imports-loader](chapter4/imports-loader.md) * [expose-loader](chapter4/expose-loader.md) * [非JS资源管理](chapter4/non-js-files.md) * [生态圈](chapter4/eco-system.md) * [Loader原理及编写](chapter4/loader-details.md) * [第五章 集成webpack](chapter5/README.md) * [Gulp](chapter5/gulp.md) * [第六章 杂谈](chapter6/README.md) * [jQuery的引入](chapter6/jquery.md) * [TypeScript和Vue](chapter6/ts-and-vue.md) ================================================ FILE: zh-cn/chapter1/README.md ================================================ # 第一章 模块化 TODO:模块化简介 ================================================ FILE: zh-cn/chapter1/ancient-times.md ================================================ # 原始时代 原始时代场景比较简单,较少碰到命名冲突和复杂依赖的场景,问题不突出。 ================================================ FILE: zh-cn/chapter1/modular-age.md ================================================ # 模块化时代 在忍受了命名空间一大串的名字很多年之后,终于有了模块化。促使模块化诞生的另一个因素是依赖管理的问题。 ## 限制 浏览器对资源加载有同源策略限制,也不支持编程化加载资源。(支持加载,不告诉你加载结果,自己猜。) 最终大部分加载器选择通过` ``` `example1.1.js`: ```javascript define([ ],function(){ alert('hello world!'); }); ``` 同样使用webpack进行编译,用法和前文使用的完全一样: ```sh webpack example1.1.js bundle1.1.js ``` 同样打开HTML文件,同样弹出“hello world!”的弹窗。(这里就不截图了。) ## 解析 我们同样打开编译后的文件分析一下,请用力点击。 可以看到,编译(就是打包的意思,后文可能会乱入,请习惯)后的文件有53行(非模块化的例子中是50行),结构仍然是一个Runtime + 模块数组,而且1到41行和前面非模块化的例子是完全一样的。 第45行即第一个模块的包裹函数,与前面非模块化的例子相比,多了一个`__webpack_require__`参数(也就是前一节说的,如果有必要的话,还有`require`参数的意思)。如果在源文件中有使用`require`引用其它模块的话,那么使用`require`的地方经过编译之后都会变成`__webpack_require__`。关于这一点,后面会涉及到的时候会有更详细的论述,此处就不再深入。 第45至52行之间即是模块本身了,当然也包含了包裹函数。如果智商正常的话,应该还是会觉得这个模块有点鬼斧神工吧?哦,也就是晦涩难懂的意思。我们稍微整理一下: ```javascript function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, // AMD依赖列表 __WEBPACK_AMD_DEFINE_RESULT__; // AMD factory函数的返回值,即模块内容 __WEBPACK_AMD_DEFINE_ARRAY__ = []; // 执行factory函数,获取返回值作为模块内容 // 函数体使用.apply调用,函数体中this为exports // 形参则分别对应依赖列表中的各个依赖模块 __WEBPACK_AMD_DEFINE_RESULT__ = function(){ alert('hello world!'); }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__); // 如果模块内容不为空,则通过module.exports返回 // 如果为空,则不处理,在Runtime中声明为{} if(__WEBPACK_AMD_DEFINE_RESULT__ !== undefined){ module.exports = __WEBPACK_AMD_DEFINE_RESULT__; } } ``` 可以看到,尽管我们的例子中并没有声明什么依赖,但webpack还是为AMD模块做了很多准备工作,比如获取依赖模块内容并传给factory函数之类。主要逻辑在上面代码的例子中已经注释,就不再多解释。 值得注意的是,在模块的最后,仍然是通过`module.exports`导出模块内容的,而Runtime中则不管是否AMD都完全一样。这种在不同模块化方案下打包后结构高度统一的方案为webpack带来了诸多好处,因为webpack只需要在模块入口导出这一块处理好不同模块化的差异即可,对后续的模块加载和优化等等都打下了坚实的基础。当然,目前可能还感觉不到这些好处,但是到目前为止,你应该可以非常直观地感觉到,webpack的确能同时支持多种模块化方案混合使用。 > 为何webpack能同时使用多种模块化(及非模块化)方案的模块而传统的require.js / sea.js之类的方案则不行?这是因为webpack对模块的处理是在编译阶段,针对每一个模块都可以针对性地分析,然后对不同方案加以不同的包裹方案,最后生成可供浏览器运行的代码。而require.js之类的方案必须保证在运行时阶段能正确地引入模块并运行。 > > 以require.js为例,在不做包裹的情况下,require.js完全无法感知非模块化JS文件的运行状态和结果,因此无法纳入其管理体系。 > > 此外,require.js必须在全局定义`require`和`define`方法,而如果此时使用` ``` main.js ```javascript var a = require('./a'); var b = require('./b'); a.doSth(); b.doSth(); ``` 这个例子中,`main.js`由HTML直接引用,是整个程序逻辑开始的地方,因此是入口文件,而被引用的`a`和`b`则是由`main.js`引入和调用,因此不是入口文件。 一般而言,我们会将一些逻辑提取封装后放到独立的文件中,最后由入口文件引入来调用它们提供的方法完成整个程序逻辑。也就是一般入口文件关注整体流程,而非入口文件关注公共某一部分的实现。 ================================================ FILE: zh-cn/chapter2/node-modules-and-npm.md ================================================ # Node和NPM 咦,明明在说前端代码,怎么突然要说Node和NPM?等等,哪里有说我在说前端代码?明明说的是JS代码。 好吧,前面的例子的确是在说前端代码,而且本指南全篇都将聚焦前端代码,但现在一个明显的趋势是前后端越来越趋向于融合,因此了解一些和Node/NPM的知识对于我们日常开发是有好处的。 上面的都是大道理,具体的事实大致有这些: 1. NPM已经不再是node package manager,而只是一个包管理软件,在NPM的愿景中是有前端代码这一块的 2. 越来越多的前端库也选择将代码发布到npm,包括jQuery / Angular / react等 3. 前端开发已经高度依赖于Node带来的生态端,比如各种各样的工具 4. 由于CommonJS在前端开发中应用的成熟,复用Node的代码成为可能(且越来越方便) ## 引用Node模块和NPM模块 既然webpack支持在前端使用CommonJS模块规范,那么是否意味着我们可以直接使用NPM模块,甚至是Node内置的模块呢?答案是肯定的,我们看一个例子: 首先准备同样的HTML和JS文件,不同的是,这次我们需要使用`npm init`准备一个`package.json`文件,因为安装npm依赖时需要用到。 ```sh npm init ``` 接下来一顿回车,就生成了一个`package.json`。然后安装一个npm模块`cookie`,用于解析和生成cookies串。 ```sh npm install cookie --save ``` > `--save`会将依赖写入`package.json`,下次直接使用`npm install`即可安装依赖。 接下来编写JS文件`example1.1.js`: ```javascript var url = require('url'); var urlResult = url.parse('http://webpack.toobug.net/zh-cn/index.html'); console.log(urlResult); var cookie = require('cookie'); var cookieResult = cookie.parse('name=toobug; subject=webpack;'); console.log(cookieResult); ``` 在这段代码里,我们分别使用Node内置的模块`url`和NPM中的模块`cookie`来解析字符串并输出结果。我们将这段JS分别在Node和浏览器中(经webpack编译)运行,最终输出如图: ![Node](../images/chapter2/node-modules-and-npm/1.1.1.png) Node.js输出截图 ![浏览器](../images/chapter2/node-modules-and-npm/1.1.2.png) 浏览器输出截图 也就是说,我们可以直接在浏览器端复用Node和NPM的代码了!不知道此时的你是否会感到很兴奋?!这意味着我们的代码可以前后端复用了,而更重要的是,前端也可以使用NPM海量的模块了,就像上例中我们使用了`cookie`这个模块,我们手中的工具一下子变强大了好多倍! ## Node模块和前端使用的CommonJS Node使用的模块规范也是CommonJS,所以理想情况下,是可以做到代码在Node和浏览器中复用的。但这里面有几处关键的差异可能导致无法复用: 1. Node的模块在运行时会有一个包裹函数,下面详述 2. 浏览器并不支持所有的Node模块,因此部分使用了Node API的模块无法在浏览器中运行 首先我们来看一下Node模块在运行的时候真相是怎样的,假设我们有如下模块`example1.1.js`: ```javascript var me = {}; module.exports = me; ``` 这是一个非常简单的Node模块。不知道大家在写Node模块的时候是否有好奇过,这里的`module`(以及`require` / `exports` / `__filename` / `__dirname`)是从哪里来的?因为按照对JS的认知,如果它不是一个局部变量(含函数形参)的话,那么只能是全局变量了。 难道这些变量是全局变量?然而当我们打开Node的命令行去访问的时候又明明白白地告诉我们是`undefined`: ```sh > console.log(global.exports) undefined > console.log(global.__dirname) undefined ``` > 按照Node的文档,`global.require`确实是存在的,还有`.cache` / `.resolve()`等成员,但每个模块中使用的`require`仍然是局部变量,并非全局`require`。 这到底是怎么回事呢?如果在运行的时候去查看它的话,它会变成这样: ```javascript (function (exports, require, module, __filename, __dirname) { var me = {}; module.exports = me; }); ``` > 可以使用`node-inspector`去远程调试Node代码,于是就能看到模块运行时的真实代码。 可以看到,我们的模块代码在运行的时候是被包裹了一层的,而上面列的这些变量正是在这个包裹函数中作为形参传入的。 其中`module`指向模块本身,`module.exports`和`exports`是等价的,表示模块要导出供调用的内容,`__filename`表示当前模块的文件名,`__dirname`表示当前模块所在路径。 因此,并不是所有的Node模块都能为浏览器所用。尽管如此,webpack也还是为这些包裹函数带来的新变量(形参)提供了模拟,可以在浏览器端使用的代码中注入这些变量。由于使用得少,而且该选项在CLI中并没有提供,需要另配config文件,故此处不再演示。 ================================================ FILE: zh-cn/chapter2/non-moduler.md ================================================ # 非模块化文件打包 为了演示webpack的强大,我们将首先演示非模块化文件打包。 ## Demo 首先准备一个HTML(`example1.1.html`): ```html webpack.toobug.net ``` > 前面解释过,webpack是一个开发时进行打包的工具,因此我们需要准备两份文件,一份是用于开发维护的源码,一份则是由webpack打包生成的文件。 > > 在这个示例中,我们关注源码就好。如果是放到实际项目中,则也需要仔细规划打包后文件的路径。 首先我们使用非模块化的方案,准备我们的源文件`example1.1.js`: ```javascript alert('hello world'); ``` 接下来使用webpack将它打包: ```sh cd {index.html所在目录} webpack example1.1.js bundle1.1.js ``` 此时就可以看到目录下生成了一个`bundle1.1.js`,正是我们在html中引用的JS文件。 访问一下`example1.1.html`,则可以看到我们的弹出框。 ![1.1.1](../images/chapter2/non-moduler/1.1.1.png) ## 解析 看到这里,你可能会开始怀疑人生了:你真的不是在逗我玩吗?这么简单一个demo,我直接引用源文件不就好了?干嘛要用webpack打包,多此一举? 这个问题,我也无法回答你,非模块化的文件被模块化打包工具支持,本来就是一件很神奇的事情。至于初衷,我也只能想到是为了让开发者能更低成本地迁移到webpack上来。 不过,为了保证我真的没有忽悠你,我们还是可以看一看打包之后的文件:。可以看到,一个原本1行的JS文件被打包成了一个50行的文件。而这剩下的49行到底是什么呢?我们简单解析一下: 整体上看,文件被分为两个部分:第1至41行,是一个函数定义,这也就是官方文档中提到的**Runtime**,作用是保证模块的顺利加载和运行。第45至49行则是我们原来写的JS文件,只是被包裹了一个函数,也就是**模块**。运行的时候模块是作为Runtime的参数被传进去的,也就是这样的形式: ```javascript (function(modules){ // Runtime })([ // 模块数组 ]) ``` 这里面特别值得注意的一点是第20行和第45行。 ```javascript // 第20行 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 第45行 function(module, exports) { ``` 其中第45行是模块被包裹的函数,给了`module`和`exports`参数。(如果有需要的话,还会给出`require`参数。)而这两个参数本质上都是Runtime中定义的`module.exports`,是一个空对象(第14行)。这样就实现了使用Common.js的方式来定义模块返回值。不过由于我们还在讨论非模块化的文件,就不深入。 真正值得注意的是第20行,使用了`.call`,第一个参数是`module.exports`,这就导致模块的包裹函数的作用域中的`this`指向了`module.exports`。这会带来两个后果: 1. 模块中无法使用`this`指代全局变量(浏览器中就是`window`) 2. 模块中可以使用`this.xxx`来指定模块包含的成员,类似Common.js中`exports.xxx`的方式(感觉我们找到了除AMD/Common.js之外的另一种模块化规范,不过因为webpack官方并没有强调这个,我们也只是代过。) ## 影响 当然,聪明的你肯定早就意识到了另一个更明显的结果,即模块不是暴露在全局作用域下了。也即通过`var xxx`的方式定义的`xxx`变量不再挂在全局对象下。这可能是在非模块化的代码迁移到webpack中碰到的最大的问题,需要手工将`var xxx`的定义方式改为`window.xxx`。 同样,由于模块源码是采用非模块化的方案编写的,因此没有通过AMD的`return`或者CommonJS的`exports`或者`this`导出模块本身,这会导致模块被引入的时候只能执行代码而无法将模块引入后赋值给其它模块使用。 例如上面的`example1.1.js`,当我们引入的时候(以CommonJS为例),`var a = require('example1.1');`,此时`a`为`undefined`。 你可能觉得这样好像没什么意义是吧?但是事实上有大量的模块是用这种方式编写的,包括著名的Angular.js(1.4以下),这会导致无法直接使用`var angular = require('angular')`来引入`angular`,需要通过额外的方式来做(exports-loader),后面详述。 ================================================ FILE: zh-cn/chapter2/umd.md ================================================ # UMD模块打包 按理说,分别讲完非模块化、AMD、CommonJS的打包后,并没有必要再专门引入一篇讲UMD打包的。但因为UMD的实现中依赖一些特殊的变量,因此还是提一下。 首先回顾一下UMD的模块定义: ```javascript (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['b'], factory); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require('b')); } else { // Browser globals (root is window) root.returnExports = factory(root.b); } }(this, function (b) { //use b in some fashion. // Just return a value to define the module export. // This example returns an object, but the module // can return a function as the exported value. return {}; })); ``` 上面的代码来自。我们按这样的方式来定义一个模块`example1.1.js`(去掉了对`b`的依赖),看看webpack会如何处理。 打包后的代码见,可以看到,使用UMD声明的模块会默认按照AMD的方式去打包。而核心的一句就是第48行,原本是 ```javascript if (typeof define === 'function' && define.amd) { ``` 被webpack直接替换成了 ```javascript if (true) { ``` 可见webpack还是相当聪明的!既满足了AMD的判断条件,又没有真的在全局注入`define`变量,这样就不会像require.js一样,一旦引入就无法再使用` ``` 运行时截图如下: ![../images/chapter3/common-chunks-plugin/1.png](../images/chapter3/common-chunks-plugin/1.png) ## 另一个问题 上面的代码成功地将公共模块`a`和`b`提取出来了。但不知道看到此处,你的心里是否会有点疑问。 如果你还没有的话,我们一起来看一下下面这些东东: 1. 什么是入口文件?如果你还记得前面我们给出的定义的话,就会发现,这个地方有两个入口文件! 2. 模块化方案应该允许多个入口文件吗?应该吗?不应该吗?应该吗?不应该吗? 3. 如果模块规划调整了,`common.js`消失了,或者增加了一个`common.2.js`,我应该修改每一个HTML引入的部分吗? 其实写到这里,我是有点迷茫的,按照我对模块化方案的认知,我的观点是: 1. 入口文件应该只有一个,其它的逻辑全部由入口文件处理,因此不应该允许多入口文件 2. 模块规划应该在模块化方案内部完成,不应该还需要时时调整模块调用入口 ================================================ FILE: zh-cn/chapter3/config.md ================================================ # 基本配置项 ## `entry`和`output` 首先我们写一个简单的配置文件,将前面我们用到的命令行参数放到配置文件中来。 `webpack.config.js`: ```javascript module.exports = { entry:'./example1.1', output:{ filename:'bundle1.1.js' } }; ``` 示例文件仍然使用CommonJS打包示例中的JS文件: ```javascript module.exports = { sayHello:function(){ alert('Hello World!'); } }; ``` 然后直接使用`webpack`打包即可: ```sh webpack ``` 输出 ``` Hash: 0cf5b5109a8f4bf34ae5 Version: webpack 1.12.2 Time: 70ms Asset Size Chunks Chunk Names bundle1.1.js 1.48 kB 0 [emitted] main [0] ./example1.1.js 83 bytes {0} [built] ``` 同时生成了`bundle1.1.js`,可见配置文件的确是生效了的。代码见。 ### `output.filename`中的占位符 `output.filename`除了可以指定具体的文件名以外,还可以使用一些占位符,包括: - `name` 模块名称 - `hash` 模块编译后的(整体)Hash值 - `chunkhash` 分片的Hash值 使用的方式就是在`output.filename`的中使用`[name].js`或者`my-[name]-[hash].js`之类的,一看就明白。但这三个值具体是从哪里来的呢? 首先,我们一次有可能要打包很多模块,而不止是上例中那样只有一个`example1.1.js`,因此会碰到支持多个入口文件(`entry`)的情况,每一个入口都需要有自己的名字,具体对应`entry`的写法而言,有如下几种情况: ```javascript entry:'./example2.1' // 或者 entry:['./example2.1','./example2.2'] ``` 这种情况下,模块是没有名字的,webpack会使用`main`作为模块名字,因此像下面这种用数组来指定入口的情况,模块名会重复,而此时webpack会将它们的代码合并打包! ```sh Hash: 1af82371840be6a233d2 Version: webpack 1.12.2 Time: 101ms Asset Size Chunks Chunk Names main.js 1.76 kB 0 [emitted] main [0] multi main 40 bytes {0} [built] [1] ./example2.1.js 83 bytes {0} [built] [2] ./example2.2.js 84 bytes {0} [built] ``` 注意上方的`multi main`字样,表示有多个模块名为`main`。这种情况下的代码见,里面包含了使用`[name]`和`[hash]`打包出来的代码,均包含了`example2.1`和`example2.2`的代码。 另一种是webpack比较推荐的多入口写法: ```javascript entry:{ 'example2.1':'example2.1.js', 'example2.2':'example2.2.js' } ``` 这种写法中,名字和模块文件名一一对应,每个模块都有独立的名字。因此这里的`[name]`可以理解成模块名字。 事实上,在webpack的文档中,这个name是指“chunk name”,即分片的名字,这里需要先剧透一下后面要说的“分片”的概念。所谓分片就是指一个入口模块的代码有可能会被分成多个文件,还有一些文件可能是来自模块的公共代码,而不是入口模块。因此这里的`[name]`并非严格与入口模块一一对应。 了解了这些情况之后,`[hash]`和`[chunkhash]`就自然好理解了,一个是指本次打包相关的整体的hash,一个是指分片的hash。 看示例: ```javascript module.exports = { entry:{ 'example3.1':'./example3.1', 'example3.2':'./example3.2' }, output:{ //这里分别用hash和chunkhash,结果不一样 filename:'[name]-[hash].js' //filename:'[name]-[chunkhash].js' } }; ``` 为了让两个模块不一样,我们将`example3.1`和`example3.2`中`alert`的内容做了修改,保证它们的内容是不一样的。用`[hash]`时打包的结果: ```sh Hash: 6f17d6321f8580500bc9 Version: webpack 1.12.2 Time: 73ms Asset Size Chunks Chunk Names example3.1-6f17d6321f8580500bc9.js 1.48 kB 0 [emitted] example3.1 example3.2-6f17d6321f8580500bc9.js 1.48 kB 1 [emitted] example3.2 [0] ./example3.1.js 88 bytes {0} [built] [0] ./example3.2.js 88 bytes {1} [built] ``` 可以看到两个文件hash值是一样的,这就是所谓整体hash的意思(官方文档叫作`bundle`的hash值)。 用`[chunkhash]`时打包的结果: ```sh Hash: 87ac4d29062084750a92 Version: webpack 1.12.2 Time: 75ms Asset Size Chunks Chunk Names example3.1-ef6b40ba3b9335fc2551.js 1.48 kB 0 [emitted] example3.1 example3.2-b92fc07f9784897342c5.js 1.48 kB 1 [emitted] example3.2 [0] ./example3.1.js 88 bytes {0} [built] [0] ./example3.2.js 88 bytes {1} [built] ``` 两个文件hash值是不同的,也就是每一个分片的hash都不一样。 代码见。 ## `output.path` 有时候我们希望输出的文件不在当前目录(其实大部分时候都是这样),比如源码在`src`目录,输出的文件在`dist`目录,此时就需要用到`output.path`来指定输出路径。 > `output.path`也可以使用占位符。 ```javascript entry:{ 'example4.1':'src/example4.1' }, output:{ filename:'[name].js', path:'./dist' } ``` 你肯定能猜到,文件会打包到`dist/example4.1.js`,这并没有什么好惊奇的,对,我是说没什么好演示的。 真正值得注意的是,如果你的模块是存放在子目录中的,而你又想保持这种目录结构到打包后的`dist`中,怎么办?没听懂是吧,就是这种情况: ``` src/ example4.1.js hello/ example4.2.js ``` 希望打包之后是这样: ``` dist/ example4.1.js hello/ example4.2.js ``` 这种情况下,子目录并不能由`output.path`配置而来,而应该将目录写到模块名上,配置文件变成这样: ```javascript entry:{ 'example4.1':'./src/example4.1', 'hello/example4.2':'./src/hello/example4.2' }, output:{ filename:'[name].js', path:'./dist' } ``` 注意这里的`filename`一定要包含`[name]`才行,因为路径信息是带在模块名上的。 代码见。 ================================================ FILE: zh-cn/chapter4/bundle-loader.md ================================================ # bundle-loader bundle-loader是一个用来在运行时异步加载模块的loader。 ```javascript // 在require bundle时,浏览器会加载它 var waitForChunk = require("bundle!./file.js"); // 等待加载,在回调中使用 waitForChunk(function(file) { // 这里可以使用file,就像是用下面的代码require进来一样 // var file = require("./file.js"); }); // todo:这句注释说的是? // wraps the require in a require.ensure block ``` 上面的例子中,在`require`时文件就会加载,如果你想在使用的时候再加载的话,可以这样: ```javascript var load = require("bundle?lazy!./file.js"); // 只有在调用load的时候才会真正加载 load(function(file) { }); ``` 但前面我们已经在“分片”相关的内容中知道,将代码分片之后,本身就是异步加载的。为什么要使用bundle-loader呢? 这是因为webpack在进行分片的时候,会根据“分割点”,分片配置项等各种情况选择性地将各个模块打包在一起。例如: ```javascript require(["./f1", "./f2"], function(f1, f2) {/*...*/}); ``` 在打包的时候,`f1`和`f2`会被打包到同一个文件中去(也可能还有其它的文件一起),这样加载的时候`f1`和`f2`是一起加载的。 而如果使用bundle-loader的话,则是独立的文件和独立的请求: ```javascript var f1 = require("bundle!./f1"); var f2 = require("bundle!./f2"); ``` `f1`和`f2`是独立打包和请求的。 这有什么意义呢?是的,如果`f1`和`f2`都是确定的,当然是打包到一起更好,能很好地减少浏览器发起的请求,加快页面加载速度。但如果模块名是动态的呢? ```javascript function loadPage(pageName, callback) { try { require(["./pages/" + pageName], function(page) { callback(null, page); }); } catch(e) { calback(e); } } ``` 这种情况下webpack为了保证不管`pageName`传什么都能正确加载,会将`./pages/`目录下的所有文件打包到一个文件中去,而很多时候,我们更希望每传一个`pageName`就动态加载一个文件,而不是全部加载。此时就可以用bundle-loader解决: ```javascript function loadPage(pageName, callback) { try { var pageBundle = require("bundle!./pages/" + pageName) } catch(e) { return callback(e); } pageBundle(function(page) { callback(null, page); }) } ``` 每个模块会被打包到一个独立的文件中去,加载时也只会加载一个模块的内容。 ================================================ FILE: zh-cn/chapter4/exports-loader.md ================================================ # exports-loader exports,导出的意思,顾名思义,这个loader是用来将(模块中的)某些内容导出的。之所以为“模块中的”加上括号,是因为实际上只要在模块中能被访问到的成员(变量)都可以被导出,当然也包括全局变量。 > export导出在这里有特定含义,指将模块中的内容暴露出来,供使用方使用。例如CommonJS中的`exports.xxx=xxx`或者`module.exports=xxx`,以及AMD中的`return xxx`都叫导出,导出后外部模块引用时就可以使用被导出的部分。没导出的部分将作为模块私有部分,外部无法访问。 ## 导出全局变量 在实际使用中,用`exports-loader`最多的场景是将某些不支持模块化规范的模块所声明的全局变量作为模块内容导出。以Angular.js为例(1.3.14以下版本),它不支持模块化引用,因此如果直接使用以下代码引用`angular`是无效的: ```javascript var angular = require('angular'); ``` 此时,`angular`仍然是一个挂载在`window`上的全局变量,而`require`返回的却是`undefined`,导致上述`angular`变量为空。此时就需要我们使用`exports-loader`将全局的`window.angular`作为`angular`模块的返回值暴露出来。 看一个例子,在这个例子中,我们没有真的引用`angular.js`,而是在`example1.2.js`中声明了一个全局变量`HELLO`: ```javascript window.Hello = function(){ console.log('hello from global Hello() function'); }; ``` 接下来,在`example1.1.js`中引用这个模块: ```javascript var Hello = require('./example1.2'); Hello(); ``` 然后直接使用webpack打包,生成`bundle1.js`,运行截图如下: ![exports-loader](../images/chapter4/exports-loader/1.png) 可以看到,由于`example1.2`并没有导出模块,导致`example1.1`在引用的时候报错,找不到`Hello`这个函数。 此时就轮到`exports-loader`上场了。我们建立一个`webpack.config.js`: ```javascript module.exports = { module:{ loaders:[ { test: require.resolve('./example1.2'), loader: "exports?Hello" } ] } }; ``` 其中的`test`表示使用`loader`的条件,这里使用了`require.resolve`解析出来的路径,表示只处理`example1.2.js`,loader中指定了`exports-loader`,参数为`Hello`,意为将`Hello`作为模块导出值。 重新打包生成`bundle2.js`,运行截图如下: ![exports-loader](../images/chapter4/exports-loader/2.png) 可见`Hello`函数已被正确调用。 查看`bundle2.js`中的代码可以清楚地看到`HELLO`被导出的过程: ```javascript /***/ function(module, exports) { window.Hello = function(){ console.log('hello from global Hello() function'); }; /*** EXPORTS FROM exports-loader ***/ module.exports = Hello; /***/ } ``` > 注:这里其实有两个示例,分别生成了`bundle1.js`和`bundle2.js`,由于`bundle1.js`需要在`webpack.config.js`生效前创建,因此如果你克隆代码后自己运行的话,在生成`bundle1.js`前请将`webpack.config.js`改名,否则其中的配置会生效,最终效果和第二例一样。 ## 导出局部变量 如前文所述,`exports-loader`可以导出一切在模块内可以访问的变量,因此如果模块内定义了一个局部变量,也是可以导出的,方法和上面的例子几乎完全一样,这里就不再演示。 ## 更多用法 上面例子中的配置文件是通过`webpack.config.js`来指定的,你也可以选择用其它方法来指定,详情见[使用loader](./using-loaders.html)。 此外,上面例子中我们只导出了一个变量,此时该变量就是模块被引用时的值(通过`module.exports`导出)。事实上,`exports-loader`还可以支持同时导出多个变量,例如`exports?HELLO,WORLD`会生成如下代码: ```javascript exports.HELLO = HELLO; exports.WORLD = WORLD; ``` 此时模块的导出值是一个对象,其中的各个键值对是我们指定的变量,引用时需要使用类似`require('example1.2').HELLO`的形式。 `exports-loader`还支持变量名和导出名不同,例如`exports?HELLO=obj.hello,WORLD=shijie`会生成如下代码: ```javascript exports.HELLO = obj.hello; exports.WORLD = shijie; ``` 一目了然,不再解释。 本文全部示例代码见。 ================================================ FILE: zh-cn/chapter4/expose-loader.md ================================================ # expose-loader > 状态:草稿 expose是暴露的意思,那么expose-loader的作用即是将变量暴露到window对象下成为全局变量。 ## 使用 ```javascript require('expose?GLOBAL_VAR!example.js'); ``` 在使用expose-loader之后,模块原本要导出的内容(`module.exports`)会被暴露到全局变量中,而全局变量的名字则是上面示例中的`GLOBAL_VAR`。这个全局变量的名字是可以自己定义的。 例如官方有一个示例,将`React`暴露到全局变量: ```javascript require('expose?React!react'); ``` 要将模块导出的内容暴露给多个全局变量的话,可以使用多次expose-loader: ```javascript expose?$!expose?jQuery! ``` todo: 与exports-loader结合使用 ================================================ FILE: zh-cn/chapter4/imports-loader.md ================================================ # imports-loader > 状态:草稿 imports,顾名思义是导入的意思,这个loader的作用与exports-loader刚好相反,是用来将其它模块导入到当前模块中。这个loader常常在处理一些非模块化规范编写的文件时被用到。 ## 背景 举个简单的例子,有模块`b`,依赖全局变量`window.a`,那么在没有使用模块化规范的情况下,有可能它的代码中会直接写`a`: ```javascript // 模块b直接依赖全局变量a a.xxx(); ``` 而如果`a`经过webpack打包,则很有可能不会暴露全局变量,此时就需要使用imports-loader来对`a`进行导入。 ## 使用 > todo:例子 ```javascript require('imports?$=jquery!./example.js'); require('imports?$=jquery,angular,config=>{size:50}!./file.js'); ``` ## 典型使用场景 - 为jQuery插件注入$变量 `imports?$=jquery` - 自定义angular `imports?angular` - 让umd模块检测不到define方法从而避免使用amd规范 `imports?define=>false` - 将模块中的`this`还原为`window` `imports?this=window` 一目了然,不再解释。 本文全部示例代码见。 ================================================ FILE: zh-cn/chapter4/using-loaders.md ================================================ # 使用loader 在webpack中,可以使用`require('./a')`的方式来引入`a.js`,如果你是从前文一路看过来的话会发现这并没有什么新奇的。那loader是做什么的呢? loader是webpack中一个重要的概念,它是指用来将一段代码转换成另一段代码的webpack插件。晕了没?为什么需要将一段代码转换成另一段代码呢?这是因为webpack实际上只能处理JS文件,如果需要使用一些非JS文件(比如Coffee Script),就需要将它转换成JS再`require`进来。当然,这个代码转换的过程能做的远不止是Coffee->JS这么简单,稍后将看到它的无穷魅力。 > 虽然本质上说,loader也是插件,但因为webpack的体系中还有一个专门的名词就叫插件(plugins),为避免混淆,后面不再将loader与插件混淆说,后文中这将是两个相互独立的概念。 ## 用途 webpack处理的主要对象是JS文件,而我们知道JS文件是可以做很多事情的,比如编译Less/SASS/CoffeeScript,比如在页面中插入一段HTML,比如修改替换文本文件等等。既然如此,我们能不能将这些能力集中到webpack上来呢,比如我在`require('a.coffee')`的时候,webpack自动帮我把它编译成JS文件,再当成JS文件引入进来?或者更极端一点,`require('a.css')`的时候,直接将CSS变成一段JS,用这段JS将样式插入DOM中呢? 这些,正是loader要做的事情。 ## 用法 为了言之有物,以下皆以`coffee-loader`为例来说明。 > coffee就是指coffee script啦,可以算是JS的一种方言,深受ruby/python党喜爱。虽然笔者并不使用coffee,也不提倡使用,但这个loader相对比较典型,容易理解。在生产环境中,更提倡使用ES6编写代码,然后使用babel-loader编译成ES5代码使用,但因为babel 6改成了插件式的,配置项略多,为了简单起见,先不使用这个。 `coffee-loader`的作用就是在引用`.coffee`文件时,自动转换成JS文件,这样可以省去额外的将`.coffee`变成`.js`的过程。 首先我们准备一个`example1.1.js`: ```javascript var hello = require('coffee!./example1.2.coffee'); hello.sayHello(); ``` 值得注意的是这里在`require`参数最前面加了`coffee!`,这个表示使用`coffee-loader`来处理文件内容。详细的机制稍后说明。 接下来,准备`example1.2.coffee`: ```coffeescript class Hello constructor: (@name) -> sayHello: () -> alert "hello #{@name}" module.exports = new Hello 'world' ``` 接下来,我们需要安装`coffee-loader`。webpack的每一个loader命名都是`xxx-loader`,在安装的时候需要将对应的loader装到项目目录下: ```sh npm install coffee-loader --save ``` 然后编译: ```sh webpack example1.1.js bundle.js ``` 打HTML,即可看到我们写的代码生效了。 ![coffee-loader](../images/chapter4/using-loaders/1.png) `example1.2.coffee`编译后的代码也可以拿出来看一下: ```javascript function(module, exports) { var Hello; Hello = (function() { function Hello(name) { this.name = name; } Hello.prototype.sayHello = function() { return alert("hello " + this.name); }; return Hello; })(); module.exports = new Hello('world'); /***/ } ``` 完整的代码见 ## 进阶 知道了loader的作用之后,可以再来多看一看loader的用法了。 首先,除了npm安装模块的时候以外,在任何场景下,loader名字都是可以简写的,`coffee-loader`和`coffee`是等价的,这意味着`require('coffee!./a.coffee')`和`require('coffee-loader!./a.coffee')`是等价的。这一点同样适用于下面讲到的其它用法,不再单独说明。 ### 串联 loader是可以串联使用的,也就是说,一个文件可以先经过A-loader再经过B-loader最后再经过C-loader处理。而在经过所有的loader处理之前,webpack会先取到文件内容交给第一个loader。以我们后面经常会涉及的一个例子说明: ```javascript require('style!css!./style.css'); ``` 这个例子的意思是将`style.css`文件内容先经过`css-loader`处理(路径处理、`import`处理等),然后经过`style-loader`处理(包装成JS文件,运行的时候直接将样式插入DOM中。) ### 参数 loader还可以接受参数,不同的参数可以让loader有不同的行为(前提是loader确实支持不同的行为),具体每个loader支持什么样的参数可以参考loader的文档。同样以`coffee-loader`为例,它可以指定一个名为`literate`的参数,意思是……我也不知道,猜测可能是编译非完整的coffee script文件(例如内嵌在markdown中的代码片段等),如果你知道是什么意思,请告诉我。 在上面的用法中,参数的指定方式和url很像,要通过`?`来指定,例如指定`literate`参数需要这样写: ```javascript require('coffee?literate=1!./a.coffee'); ``` 这段代码中指定了`literate`参数为`1`,如果不写`=1`的话,默认值为`true`。(`coffee-loader`官方并没有说可以为1,而是只写了`literate`,没有值)。 ### loader使用方法 loader的使用有三种方法,分别是: - 在`require`中显式指定,即上面看到的用法 - 在配置项(`webpack.config.js`)中指定 - 在命令行中指定 第一种我们已经看过了,不再说明。 第二种,在配置项中指定是最灵活的方式,它的指定方式是这样: ```javascript module: { // loaders是一个数组,每个元素都用来指定loader loaders: [{ test: /\.jade$/, //test值为正则表达式,当文件路径匹配时启用 loader: 'jade', //指定使用什么loader,可以用字符串,也可以用数组 exclude: /regexp/, //可以使用exclude来排除一部分文件 //可以使用query来指定参数,也可以在loader中用和require一样的用法指定参数,如`jade?p1=1` query: { p1:'1' } }, { test: /\.css$/, loader: 'style!css' //loader可以和require用法一样串联 }, { test: /\.css$/, loaders: ['style', 'css'] //也可以用数组指定loader }] } ``` 在命令行中指定参数的用法用得较少,可以这样写: ```sh webpack --module-bind jade --module-bind 'css=style!css' ``` 使用`--module-bind`指定loader,如果后缀和loader一样,直接写就好了,比如`jade`表示`.jade`文件用`jade-loader`处理,如果不一样,则需要显示指定,如`css=style!css`表示分别使用`css-loader`和`style-loader`处理`.css`文件。 ## 更多 loader本质上做的是一个anything to JS的转换,因此想象空间极大,从目前[官方列出的loader列表](https://webpack.github.io/docs/list-of-loaders.html)来看,大致有这样一些用途: 1. 其它语言编译到JS,包括JSON、纯文本、coffee、CSS等,也包括比较复杂的整体方案处理,比如`vue-loader`、`polymer-loader`等 2. “微处理”类,比如为非模块化文件添加一些模块化导入导出代码,对模块细节(代码)微调等,例如`exports-loader`、`expose-loader`等 3. 校验和压缩类,这一类其实最终并不生成代码,检验类如果报错就阻止构建进行,压缩类只是替换一下图片资源等 4. 纯打包类,比如`file-loader`,将资源文件一并纳入路径管理 具体的可以对照官方的loader列表一一查看。 ================================================ FILE: zh-cn/chapter6/ts-and-vue.md ================================================ # TypeScript与Vue > 本文适用于webpack 2+ ## TypeScript(ts-loader) 要使用TypeScript的话,只需要将文件名后缀改成`.ts`,并引入`ts-loader`进行处理即可。 例如我们有一个TS文件: ```typescript function a(num: number){ return num+1; } console.log(a(5)); ``` 只需要在`webpack.config.js`中配置一下(注意这是webpack 2+的配置): ```javascript module:{ rules:[{ test: /\.ts$/, loader:'ts-loader', }] } ``` 即可。 ## Vue单文件组件(vue-loader) Vue为我们提供了单文件组件的写法,例如下面的`test.vue`: ```vue ``` 这种写法需要使用`vue-loader`转换成纯JS文件才可以正常在浏览器中运行。和使用`ts-loader`类似,只要使用`vue-loader`处理即可,这里就不再演示。唯一值得注意的是`vue-loader`会需要同时安装几个模块,如果弄不清楚的话,安装`vue-loader`的时候留意一下npm的输出,把需要的模块都装上就可以了。 ## TypeScript + Vue 基本用法就是同时加上`ts-loader`和`vue-loader`。但是`ts-loader`需要加上两个选项: ```javascript options: { transpileOnly: true, appendTsSuffixTo: [/\.vue$/], } ``` `transpileOnly`的含义是指让`ts-loader`只做转译。什么意思呢?就是不加这个选项的话,它会把转义的结果写入到文件中,而不是在内存中由webpack来处理,这会导致后续loader无法处理`ts-loader`的结果。所以加上`transpileOnly`让它按webpack的操作来,这样后续loader就可以继续处理。 `appendTsSuffixTo`的含义是碰到`.vue`结尾的文件时,加上`.ts`的后缀,这样`ts-loader`就会去处理`.vue`文件中的ts代码。 另外在使用TypeScript编写Vue代码时,可能会碰到一些类型上的问题,可以参见Vue的官方文档: