「推荐收藏」提高组件库 Level 必做好这六件事
基础概念
随着前端工程化的概念越来越深入人心,脚手架应运而生。简单来说,「前端脚手架」就是指通过选择几个选项快速搭建项目基础代码的工具。前端脚手架可以有效避免我们 ctrl + C 和 ctrl + V 相同的代码框架和基础配置。
脚手架思路
在动手开始开发脚手架 CLI 之前我们先捋一下思路,纵览业界比较流行的几个脚手架,会发现虽然它们功能丰富度和复杂程度不一样,但是总体来说都会包含以下基本功能:
CLI 搭建项目
CLI 运行项目
脚手架架构图
通过架构图了解下脚手架的大致工作流程
插件依赖
开发脚手架常用插件
创建脚手架
初始化项目
下载 node,创建一个新的文件夹,cmd 进入到文件夹目录运行:npm init,生成 package.json 文件
进入项目
修改 package.json 中的 bin 参数,专门放置用户的自定义命令,指定可执行文件的位置,bin 里的命令是可执行命令,模块安装的时候如果是全局安装,则 npm 会为 bin 中配置的文件创建一个全局软连接,在命令行工具里可以直接执行
项目中新建 src 文件夹,新增 gfe-cli.js,文件为命令入口文件,文件第一行必须是 #!/usr/bin/env node,代表执行这个脚本的时候,调用/usr/bin 下的 node 解释器。
处理命令行
我们通过 commander 来设置不同的命令。
command 方法设置命令的名字、description 方法是设置命令的描述、alias 方法设置命令简称【懒人必备】、options 设置命令需要的参数。commander 更详细的文档可以去 commander 官网查看。
我们脚手架先加入三个命令:项目创建、项目初始化、项目启动。源代码在 src/gfe-cli.js 中。
项目模板
脚手架可以帮助我们快速生成一套指定的项目结构和配置,最常用的方式就是我们提前准备好一套通用的、易用的、规范的项目模板存放在指定位置,在脚手架执行创建项目命令的时候,直接将 **准备好的模板 **拷贝到目标目录下。
项目模板存放位置方式
第一种是和脚手架打包在一起,在安装脚手架的时候就会将项目模板存放在全局目录下了,这种方式每次创建项目的时候都是从本地拷贝的速度很快,但是项目模板自身升级比较困难。
第二种是将项目模板存在远端仓库(比如 gitlab 仓库),这种方式每次创建项目的时候都是通过某个地址 动态下载 的,项目模板更新方便。选择第二种,解耦了模板和脚手架,方便更新维护。
代码源码:
如果下载完项目,需要执行 shell 命令
node 脚本中,执行指定的 shell 命令
执行进程命令 npm 需要判断 const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
配置全局 CLI 命令
我们的脚手架开发完成发布到 npm 后,可以通过 npm install -g gfe-cli **全局安装 **的方式安装就可以直接使用 CLI 命令了。
但是开发过程中为了 **方便调试和实时同步 **修改,需要另外的方式将 CLI 命令链接到全局。
可以在 gfe-cli 目录下执行 **npm link **,该命令可以将 gfe-cli 下的 bin 命令软链接到全局,直接使用。
Tips:npm link 的时候遇到过几个小坑跟大家分享一下
在开发的过程中可能会遇到 **执行命令失败 **的情况,比如 zsh: command not found: gfe-cli。
发布配置
name 是包的名字,可以直接写包名,比如 cli,或者添加域,类似于 @gfe/cli 这种,@后面是你 npm 注册的用户名。key 为包的关键字。
.npmrc 文件,发布配置文件
.npmignore 文件,忽略上传文件
开发注意
简述 ESM 和 CJS 模块
早期 Javascript 这门语言是没有模块化的概念的,直到 nodejs 诞生,才把模块系统引入 js。nodejs 使用的是 CJS(Commonjs)规范,也就是我们平时所见的 require、module.exports。而 js 语言标准的模块规范是 ESM(Ecmascript Module),也就是我们在前端工程大量使用的 import、export 语法。nodejs 已经在逐步支持 ESM,目前很多主流浏览器也已经原生支持 ESM。
项目使用的是 ESM 还是 CJS?
Node.js 8.5.0 增加了 ESM 的实验性支持,使用**--experimental-modules **标识,加上以 **.mjs **为后缀的文件名可以让 nodejs 执行 ESM 规范导入导出的模块。例如:
Node.js 12.17.0,移除了**--experimental-modules **标识。虽然 ESM 还是试验性的,但已经相对稳定了。
之后的版本,nodejs 按以下流程判断模块系统是用 ESM 还是 CJS:
如何让 require 和 import 在同一文件中使用
ES6 标准发布后,module 成为标准,标准的使用是以 export 指令导出接口,以 import 引入模块,但是在我们一贯的 node 模块中,我们采用的是 CommonJS 规范,使用 require 引入模块,使用 module.exports 导出接口
node 中通常引入模块是 require 语法,而非 import 语法。 可编写一个 js 文件 即支持 require 语法,又支持 import 语法
改为
运行 serve.js
nodejs 原本支持 commonjs 的模块化规范,就是 require 这类型的
如果想要使用 es6 export import 的模块化规范,启动方式:
将文件修改为 mjs 后缀,或者修改 package.json 中的 type: module
Rollup 打包注意
为何使用 Rollup 打包工具
Rollup.js 是一个模块打包工具,可以帮助你从一个入口文件开始,将所有使用到的模块文件都打包到一个最终的发布文件中(极其适合构建一个工具库,这也是选择用 rollup 来打包的原因)
Rollup.js 有两个重要的特性,其中一个就是它使用 ES6 的模块标准,这意味着你可以直接使用 import 和 export 而不需要引入 babel(当然,在现在的项目中,babel 可以说是必用的工具了)
Rollup.js 一个重要特性叫做'tree-shaking',这个特性可以帮助你将无用代码(即没有使用到的代码)从最终的生成文件中删去。(这个特性是基于 ES6 模块的静态分析的,也就是说,只有 export 而没有 import 的变量是不会被打包到最终代码中的)
问题一 报错 SyntaxError: Unexpected character '!'
入口文件 首行必须添加 #!/usr/bin/env node 用 Rollup 打包报错 可在 rollup.config.js 配置这段代码
rollup 配置文件的两个属性:banner 和 footer,这两个属性会在生成文件的开头和结尾插入一段你自定义的字符串 可新增参数 banner:'#!/usr/bin/env node'
问题二 报错 [!] Error: 'default' is not exported by ****
rollup 默认是不支持 CommonJS 模块的,自己写的时候可以尽量避免使用 CommonJS 模块的语法,但有些外部库的是 cjs 或者 umd(由 webpack 打包的),所以使用这些外部库就需要支持 CommonJS 模块
问题三 报错 (!) Unresolved dependencies
帮助 Rollup 查找外部模块 引入 rollup-plugin-node-resolve
external 属性:使用 rollup 打包,我们在自己的库中需要使用第三方库,例如 fs,path 等,又不想在最终生成的打包文件中出现 fs,path
配置 rollup.config.js
npm 发布注意
npm 发布私库成功之后,下载找不到地址?
原因:下载未配置私库地址
例如: 脚手架是**@gfe/n-cli**,需要在全局安装 -g
在全局要配置:打开 cmd 自动定位到 C:\Users\55409>
在 55409 文件夹里配置 .npmrc 文件
@gfe 需要对应私库地址 其余内部依赖走 npm 公共
版权声明: 本文为 InfoQ 作者【GFE】的原创文章。
原文链接:【http://xie.infoq.cn/article/5eba5ef485da498bd94c6e9b0】。文章转载请联系作者。
评论