{"action":"opened","issue":{"url":"https://api.github.com/repos/frontend9/fe9-library/issues/2","repository_url":"https://api.github.com/repos/frontend9/fe9-library","labels_url":"https://api.github.com/repos/frontend9/fe9-library/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/frontend9/fe9-library/issues/2/comments","events_url":"https://api.github.com/repos/frontend9/fe9-library/issues/2/events","html_url":"https://github.com/frontend9/fe9-library/issues/2","id":345538603,"node_id":"MDU6SXNzdWUzNDU1Mzg2MDM=","number":2,"title":"我的第一个 umi 插件","user":{"login":"chenkan","id":1892479,"node_id":"MDQ6VXNlcjE4OTI0Nzk=","avatar_url":"https://avatars3.githubusercontent.com/u/1892479?v=4","gravatar_id":"","url":"https://api.github.com/users/chenkan","html_url":"https://github.com/chenkan","followers_url":"https://api.github.com/users/chenkan/followers","following_url":"https://api.github.com/users/chenkan/following{/other_user}","gists_url":"https://api.github.com/users/chenkan/gists{/gist_id}","starred_url":"https://api.github.com/users/chenkan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenkan/subscriptions","organizations_url":"https://api.github.com/users/chenkan/orgs","repos_url":"https://api.github.com/users/chenkan/repos","events_url":"https://api.github.com/users/chenkan/events{/privacy}","received_events_url":"https://api.github.com/users/chenkan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-07-29T15:17:26Z","updated_at":"2018-07-29T15:17:26Z","closed_at":null,"author_association":"NONE","body":"> 光说不练假把式\r\n\r\n继上文「umi 插件体系的一些初步理解」从理论层面分析 umi 插件后，本文将实战一个迷你 umi 插件。\r\n代码源码在此：[https://github.com/frontend9/umi-plugin-demo](https://github.com/frontend9/umi-plugin-demo)\r\n可以码文互看😄\r\n\r\n### 第一步，创建 umi 简单应用\r\n首先，安装 umi\r\n```plain\r\ntnpm i umi -S\r\n```\r\n\r\n其次，编写示例页面，得益于 umi 的「约定优于配置」理念，只需要一个文件即可\r\n```javascript\r\n// pages/index.js\r\n\r\nexport default () => <div>Index Page</div>\r\n\r\n```\r\n\r\nOK，跑一下\r\n```plain\r\nnpx umi dev\r\n```\r\n\r\n![image](https://user-images.githubusercontent.com/1892479/43367720-63fb1cdc-9384-11e8-82b1-c9cd9ae030a9.png)\r\n\r\n### 第二步，创建 umi 简单插件\r\n新建 umi-plugin-hello 文件夹，在里面添加 package.json 及 src/index.js\r\n\r\n```json\r\n// package.json\r\n\r\n{\r\n    \"name\": \"umi-plugin-hello\",\r\n    \"version\": \"0.0.2\",\r\n    \"main\": \"./lib/index.js\",\r\n    \"scripts\": {\r\n      \"build\": \"node_modules/babel-cli/bin/babel.js src --out-dir lib\"\r\n    },\r\n    \"devDependencies\": {\r\n      \"babel-cli\": \"^6.26.0\",\r\n      \"babel-core\": \"^6.26.0\",\r\n      \"babel-preset-es2015\": \"^6.24.1\"\r\n    },\r\n    \"babel\": {\r\n      \"presets\": [\"es2015\"]\r\n    }\r\n  }\r\n\r\n```\r\n\r\n这里使用 babel 配置 build 命令，这样在构建时就会把源码中 ES6 转码为 ES5（社区约定，一般 npm 包都是转码的）。\r\n\r\n```javascript\r\n// src/index.js\r\n\r\nexport default function(api, opts = {}) {\r\n    api.register('modifyHTML', ({ memo }) => {\r\n      memo = memo.replace(\r\n        '</head>',\r\n        `\r\n  <script>alert(\"Wow~~~ it works.\")</script>\r\n  </head>\r\n      `.trim(),\r\n      );\r\n      return memo;\r\n    });\r\n  }\r\n\r\n```\r\n\r\n这个就是插件逻辑了：\r\n1. 调用 `modifyHTML` 这个 hook 点，并且提供一个 function 用于改写 HTML 文件。\r\n2. 这个 function 会传入 `memo`，这个 memo 即是 umi 在执行插件 hook 时的 HTML 全文内容。\r\n3. 很显然，这个插件的作用就是通过文本替换，给 HTML 文件注入一个 alert。\r\n\r\n然后，依次执行\r\n1. tnpm i\r\n2. tnpm run build\r\n3. tnpm pack\r\n\r\n就会在本地生成一个 npm 包。\r\n\r\n### 第三步，引入 umi 插件\r\n回到工程根目录，执行\r\n```plain\r\ntnpm i ~/tmp.729/umi-plugin-hello/umi-plugin-hello-0.0.2.tgz\r\n```\r\n\r\n安装上一步产出的 umi 插件 npm 包。（注意：npm 包路径使用全路径。）\r\n\r\n然后，新建 .umirc.js 引入插件\r\n```javascript\r\n// .umirc.js\r\n\r\nexport default {\r\n    plugins: [\r\n      'umi-plugin-hello',\r\n    ],\r\n  };\r\n  \r\n```\r\n\r\n最后，重新 run 一下工程，就可以了！\r\n\r\n\r\n![image](https://user-images.githubusercontent.com/1892479/43367725-781e2952-9384-11e8-94e5-a10b97e8f4cd.png)\r\n"}}
{"actor":{"display_login":"chenkan"}}