# 集成开发环境 joyer-cli  

## 遇到问题怎么办  

- 到 [这里](http://xingyun.jd.com/codingRoot/joyer/joyer-cli/issues/?state=close&page=1) 搜索问题、提交问题  
- [常见问题及常用用法](http://xingyun.jd.com/codingRoot/joyer/joyer-cli/issues/?state=close&labelName=usage&page=1)  
- [模板库](http://xingyun.jd.com/codingRoot/teams/joyer-template)  
- [跨模板通用组件库](http://xingyun.jd.com/codingRoot/teams/joyer-component)  
- 详细文档
  - [1.4.8`(current)`](./doc/index.md)  

## Node版本  

- 统一使用较新的LTS版本，推荐 `v16.20.2 (LTS)(2023-08-10)`, 安装方式[nvm](https://github.com/creationix/nvm)  

    - 原因：Node奇数版本为stable版本，偶数版本为LTS(Long Term Support)版本，[后者维护期更长，更稳定](https://nodejs.org/en/user-survey-report/#Release-Line)  


- 统一使用`npm`作为包管理工具，不使用`yarn`  

    - 原因：npm从5.x版本以后已经加入yarn的大部分特性，包括`package-lock.json`、默认`--save`、cache重写带来的安装速度提升(不输yarn)等，[详见](https://medium.com/wemake-services/is-yarn-still-a-thing-3c6886410c83)  
    - 交叉使用npm和yarn会产生功能类似的重复文件及一些未知风险，[使用比例](https://nodejs.org/en/user-survey-report/#Package-Manager-Usage)  
 

# 使用文档  

## 安装`joyer-cli`

- `npm install joyer-cli -g`  
  
## 使用`joyer-cli`

- 文档：  

  [模板贡献规则](./doc/template.md)  

  [组件贡献规则](./doc/component.md)  

  [joyer-config 配置说明](./doc/joyer-config.md)  

  [joyer init 创建新项目](./doc/joyer-init.md)  

  [joyer dev 启动本地编译环境](./doc/joyer-dev.md)  

  [joyer build 打包项目](./doc/joyer-build.md)  

  [joyer deploy 上传测试环境](./doc/joyer-deploy.md)  

  [joyer install 安装组件](./doc/joyer-install.md)  

  [joyer link 创建组件软链](./doc/joyer-link.md)  

  [joyer add 创建新页面](./doc/joyer-add.md)  

  [joyer serve 启动本地静态资源服务器](./doc/joyer-serve.md)  

  [joyer mock 启动 mock 服务](./doc/joyer-mock.md)  

  [joyer cure 将全局 joyer 环境固化到项目目录](./doc/joyer-cure.md)  

  [joyer jue 动态化三端相关命令](./doc/joyer-jue.md)  

  [joyer login 用户登录](./doc/joyer-login.md)  

  [joyer whoami 检查当前登录用户](./doc/joyer-whoami.md)  

  [joyer create 创建模板/组件](./doc/joyer-create.md)  

  [joyer clear 上传测试环境](./doc/joyer-clear.md)  


# 重要依赖及选择原因  

- webpack@4.43.0  

    - 目前为最新的稳定版本，相比3.x编译速度提升了近2倍，更好的代码分离机制，更多的模块类型支持，[详见](https://medium.com/webpack/webpack-4-released-today-6cdb994702d4)  
    - 使用其node api模式而非cli模式，目的在于有利于开发环境同时并存多个webpack版本，缺点是每个文件目录会比较大  
    * 疑问点，目前大部分项目应该是在3.x版本下构建，迁移成本？  

- webpack-dev-server@3.11.0  

    - 目前最新的稳定版本，适配webpack@4.x，v3.1.2之前的版本存在proxy的[bug](https://xwenliang.cn/p/5add9a8a9e10d5d73c000001)  
    
- @babel/preset-env@7.7.7

    - 完美解决了babel-polifyll的[问题](https://xwenliang.cn/p/5a3a410b9a06a7542c000002)，无需全量打包  

- @babel/core@7.7.7 

    - 适配@babel/preset-env@7.7.7


# 问题记录  

- `joyer install <template>` 原计划到`source.jd.com`上面专门开一个repo用来存放和维护今后要用到的模板，但由于访问需要登录，故放弃  
    - 替代方案：在joyer-cli项目中内置template目录，用于存放模板。缺点：可拓展性差，需要发版才能更新模板，耦合性较强。  
    - 后续考虑：可否把模板放到类似github的开源平台进行维护？ 
    - 结论：在git.jd.com平台建立group作为模板仓库(joyer-template)和组件仓库(vue-components/zepto-components),通过gitlab api来抽取模板和组件  
    - 缺点：需要把自己的private token绑定到环境变量`JOYER_GIT_TOKEN`，这已经是目前能想到的最小成本的方案了，后续待讨论...
    - 更新：绑定了个人的具有时效的access_token，这样就无需使用者再绑定了 @2018-12-19

- 考虑实现类似`joyer upgrade`来更新组件库？  
    - 开始考虑实现类似joyer-template的方式进行组件安装及更新，但维护成本较高且可能会有版本依赖问题  
    - 结论：和军哥讨论后决定使用模板集成组件的方式来维护组件库，把组件库内置到模版中指定的目录，通过`joyer install`命令来重新安装组件库  

- 考虑替代通过检测`process.env`的方式来区分域名及环境，原因[reading-environment-variables-is-slow-operation](https://stackoverflow.com/questions/7460552/reading-environment-variables-is-slow-operation)  
    - 结论：joyer模板中joyer-config新增字段env，然后脚手架通过DefinePlugin设置编译时变量  

- 抽离公共css的过程中发现了问题：`optimization.splitChunks.cacheGroups.{cacheGroups}.enforce: true`会产生一个空的js文件，目前还没有官方解决方案  
    - [splitChunks can create initial chunks that are empty after CSS extraction](https://github.com/webpack/webpack/issues/7300);  
    - [extract multiple css files but created a unnecessary js file](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/279);  
    - 解决方案： 将common css模块作为entry引入，然后通过webpack-fix-style-only-entries组件删除空js文件  

- 然后抽离css过程中发现新问题，在`scss`中使用`@import`引入的`common.scss`[不会被抽离](https://github.com/webpack-contrib/sass-loader/issues/628)  
    - 解决方案：编译完成后，将所有文件中引入的`common.scss`中的内容[匹配并移除](http://git.jd.com/jdjr/issues/issues/5)  

- html-webpack-plugin和html-loader同时使用，会使html-webpack-plugin注入html变量失效  
    - 实现基于joyer-config的变量系统，在配置文件中添加env字段用来放置编译相关的变量  
    - 困难：webpack.DefinePlugin不能在html文件中定义变量  
    - 解决方案：实现webpack plugin用于替换html中指定字符  

- open-browser-webpack-plugin在windows子系统linux(Bash on Windows)中存在问题，不能打开浏览器  
    - 使用兼容性更好的[opn](https://www.npmjs.com/package/opn)代替  

- 单页面应用使用history模式时，想利用HtmlWebpackPlugin输出多个index.html文件到各个路由目录，发现[它不支持相对路径](https://github.com/jantimon/html-webpack-plugin/issues/665)，导致路由目录下的index.html文件资源引用出错  
    - 目前已经[合并代码](https://github.com/jantimon/html-webpack-plugin/issues?utf8=%E2%9C%93&q=relative)但仍未发布  
    - 解决方案：`webpack-plugins/fix-html-webpack-plugin-relative-path.js` 自行解决  