{"action":"opened","issue":{"url":"https://api.github.com/repos/longyiyiyu/blog/issues/4","repository_url":"https://api.github.com/repos/longyiyiyu/blog","labels_url":"https://api.github.com/repos/longyiyiyu/blog/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/longyiyiyu/blog/issues/4/comments","events_url":"https://api.github.com/repos/longyiyiyu/blog/issues/4/events","html_url":"https://github.com/longyiyiyu/blog/issues/4","id":168517004,"number":4,"title":"webpack 学习小结","user":{"login":"longyiyiyu","id":3177308,"avatar_url":"https://avatars.githubusercontent.com/u/3177308?v=3","gravatar_id":"","url":"https://api.github.com/users/longyiyiyu","html_url":"https://github.com/longyiyiyu","followers_url":"https://api.github.com/users/longyiyiyu/followers","following_url":"https://api.github.com/users/longyiyiyu/following{/other_user}","gists_url":"https://api.github.com/users/longyiyiyu/gists{/gist_id}","starred_url":"https://api.github.com/users/longyiyiyu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/longyiyiyu/subscriptions","organizations_url":"https://api.github.com/users/longyiyiyu/orgs","repos_url":"https://api.github.com/users/longyiyiyu/repos","events_url":"https://api.github.com/users/longyiyiyu/events{/privacy}","received_events_url":"https://api.github.com/users/longyiyiyu/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-07-31T13:06:20Z","updated_at":"2016-07-31T13:06:20Z","closed_at":null,"body":"# webpack 学习小结\r\n## 1 前言\r\n打包，本质来说就是把许多零散的文件有序的合并成为一个文件，达到前端优化的效果\r\n它的前世今生就不说了，感兴趣的同学可以去学习相关知识\r\n\r\n> 构建 != 打包，反之亦然\r\n> 打包可以说是构建的一环，构建可以做更多的事情\r\n> 但是，打包永远都是构建的一个核心\r\n\r\n## 1.1 相关工具\r\n打包工具有很多，下面稍微介绍一下笔者认识的：\r\n\r\n### 1.1.1 grunt\r\n准确来说，grunt 是个构建工具\r\n它只是提供了一些基础能力，出现的较早，社区强大\r\n\r\n### 1.1.2 gulp\r\ngulp 和 grunt 很像，就不多聊了\r\n\r\n### 1.1.3 fis\r\n可以说，fis 比较大，对整个打包过程有一个核心规范和流程，并且总结并提供了打包构建中的3个核心能力\r\nfis 是一个很值得去学习的构建框架\r\n\r\n### 1.1.4 webpack\r\n这个应该是目前最受欢迎与关注的工具了\r\n就个人学习而言，相比其他工具，webpack 是一个专注于打包的工具，因为专注，所以强大\r\n\r\n# 2 打包原理\r\n打包过程实际上很简单，也非常直观，其逻辑如下图所示：\r\n![webpack1](https://cloud.githubusercontent.com/assets/3177308/17276670/68020f94-5762-11e6-85f0-71365f7f825d.png)\r\n\r\n1. 确定入口文件：所有程序都会有一个入口，就是 main 程序，打包也不例外\r\n2. 获取依赖：分析依赖，打包的关键就是按依赖的顺序来打包，因此这是打包最关键的环节\r\n3. 确认出口文件：大多数情况下，打包最终都是输出一个文件，但是也可能会打包成多个，比如common，异步文件等\r\n4. 打包：最终输出内容\r\n\r\n# 3 webpack\r\nwebpack 的基本使用就不介绍了，看一下文档就知道了\r\n实际上 webpack 的核心是**依赖分析**，把依赖分析出来了，其他都是细枝末节了\r\n比如 支持什么模块化规范，比如插件等等\r\n\r\n使用 webpack 主要是看怎么 config\r\n下面看看 webpack 官方文档的目录：\r\n![webpack2](https://cloud.githubusercontent.com/assets/3177308/17276672/7103df1e-5762-11e6-8473-edb49f489b61.png)\r\n![webpack3](https://cloud.githubusercontent.com/assets/3177308/17276673/7740cfea-5762-11e6-9ed9-4a2cdf03cad0.png)\r\n\r\n\r\n看到 config 目录那么多，就说明 webpack 的功能有多大\r\n那么多内容可能无从下手，但是大多数情况下只需要关注核心的一些配置即可\r\n下面主要讲解上图的红框部分\r\n\r\n## 3.1 entry\r\n这个就是【入口文件】配置，通过这个 option 来确定入口文件，它有3种格式：\r\n1. string：指定入口文件\r\n2. array：多个入口文件，最终打包到一起\r\n3. object：多 chunk，key 为 chunk 的 名字，value 指定这 chunk 的入口文件\r\n\r\nstring 和 array 最终会打包成一个文件，object 则可以打包出多个文件\r\n\r\n## 3.2 output\r\n配置【出口文件】\r\n它主要做两种事情：\r\n1. 出口文件名称与路径\r\n2. 出口文件的格式\r\n\r\n看下面的例子：\r\n``` javascript\r\n// js/a.js\r\nrequire('./c.js');\r\n\r\nvar a = 1;\r\n\r\n// js/b.js\r\nrequire('./c.js');\r\n\r\nvar b = 1;\r\n\r\n// js/c.js\r\nvar c = 1;\r\n\r\n// webpack.config.js\r\nmodule.exports = {\r\n    entry: {\r\n        a: './js/a.js',\r\n        b: './js/b.js'\r\n    },\r\n    output: {\r\n        path: __dirname + '/dist',\r\n        filename: \"[name].js\"\r\n    }\r\n};\r\n```\r\n1. filename 指定输出文件的文件名，不建议带路径\r\n2. path 这个指定输出文件的文件路径\r\n\r\n上面就是输出多文件的配置\r\n\r\n如果是要打包库文件，则需要用常规的模块包裹头，webpack 也能轻松支持：\r\n``` javascript\r\nmodule.exports = {\r\n    entry: {\r\n        a: './js/a.js'\r\n    },\r\n    output: {\r\n        path: __dirname + '/dist',\r\n        filename: \"L.js\",\r\n        library: 'L',\r\n        libraryTarget: 'umd'\r\n    }\r\n};\r\n```\r\n\r\n输出的L文件就有了常规模块化包裹头：\r\n``` javascript\r\n(function webpackUniversalModuleDefinition(root, factory) {\r\n\tif(typeof exports === 'object' && typeof module === 'object')\r\n\t\tmodule.exports = factory();\r\n\telse if(typeof define === 'function' && define.amd)\r\n\t\tdefine([], factory);\r\n\telse if(typeof exports === 'object')\r\n\t\texports[\"L\"] = factory();\r\n\telse\r\n\t\troot[\"L\"] = factory();\r\n})(this, function() {\r\nreturn /******/ (function(modules) { // webpackBootstrap\r\n\r\n// ...\r\n```\r\n\r\n## 3.3 resolve\r\nresolve 主要是分析依赖时的路径识别的配置\r\n上面的例子中：a.js 和 b.js 文件都是在js文件夹里面的，然后 require 的时候要用相对路径\r\n通过 resolve 可以帮助我们可以书写更加简单方便的依赖路径，比如：\r\n``` javascript\r\n// main.js\r\nrequire('a');\r\n\r\nvar main = 1;\r\n\r\n// webpack.config.js\r\nvar path = require('path');\r\n\r\nmodule.exports = {\r\n    entry: {\r\n        b: './js/b.js',\r\n        c: './main.js'\r\n    },\r\n    output: {\r\n        path: __dirname + '/dist',\r\n        filename: \"[name].js\",\r\n    },\r\n    resolve: {\r\n        root: [\r\n            path.resolve('./js/')\r\n        ]\r\n    }\r\n};\r\n```\r\n如果没有 resolve.root 的配置，则需要写成：require('./js/a')\r\n\r\n## 3.4 externals\r\nexternals 是配置外部依赖的，如果使用某些第三方库的时候，就可以通过这个配置来识别外部第三方库的依赖\r\n比如：\r\n``` javascript\r\nmodule.exports = {\r\n    entry: './main.js',\r\n    output: {\r\n        filename: 'L.js',\r\n        library: 'L',\r\n        libraryTarget: 'umd'\r\n    },\r\n    externals: {\r\n        'jquery': {\r\n            root: 'jquery',\r\n            amd: 'jquery',\r\n            commonjs2: 'jquery',\r\n            commonjs: 'jquery'\r\n        }\r\n    }\r\n};\r\n```\r\n这个配置显示将要打包的库文件要依赖 jquery 库，打包之后的文件如下：\r\n``` javascript\r\n(function webpackUniversalModuleDefinition(root, factory) {\r\n\tif(typeof exports === 'object' && typeof module === 'object')\r\n\t\tmodule.exports = factory(require(\"jquery\"));\r\n\telse if(typeof define === 'function' && define.amd)\r\n\t\tdefine([\"jquery\"], factory);\r\n\telse if(typeof exports === 'object')\r\n\t\texports[\"Q\"] = factory(require(\"jquery\"));\r\n\telse\r\n\t\troot[\"Q\"] = factory(root[\"jQuery\"]);\r\n})(this, function(__WEBPACK_EXTERNAL_MODULE_4__) {\r\nreturn /******/ (function(modules) { // webpackBootstrap\r\n```\r\n\r\n## 3.5 watch\r\n对于一个工具来说，watch 功能是非常重要的\r\n\r\n## 3.6 plugins\r\n对于一个成熟的框架，插件化是扩展性的一个重要的功能点，感兴趣的同学可以深入学习\r\n\r\n# 4 小结\r\nwebpack 是一个专注于打包的工具，它使用简单，功能强大\r\n而且可以作为一个构建框架的打包核心插件，比如grunt，gulp\r\n本文仅仅介绍了webpack的一些核心属性，不多，但是已经可以满足绝对部分需求"}}
{"actor":{"display_login":"longyiyiyu"}}