Skip to content
On this page

脚手架开发

这次我们还是在 Monorepo+pnpm 的代码基础上进行开发

package.json 配置 bin

json
"bin": {
    "wakk": "./index.js"
}

执行npm link命令,link相当于将当前本地模块链接到npm目录下,这个目录可以直接访问。默认package.jsonname为基准,也可以通过bin配置别名。 npm unlink解除链接: npm unlink chaochao-cli --location=global 只有本地开发需要执行这一步,正常脚手架全局安装无需执行此步骤。因为npm link以后,相当于全局可以执行wakk命令,这里不执行npm link命令。

删除依赖、执行命令

删除项目中已经安装好的目录,重新pnpm install,让demo1项目下生成wakk的软链接。这个时候去demo1打开终端,运行wakk会报如下错误:

ts
wakk: The term 'wakk' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

执行npx wakk则可以正常执行,所以脚手架发布以后,可以全局安装使用,也可以单个项目安装,然后配置npx使用。

到这里我就弄懂了如何配置一个可以不使用npm run执行的脚手架命令,至于后续的如何拉去git远程模板,配置友好的脚手架命令提示等内容,以后有时候再补。 可以参考: https://juejin.cn/post/7086340583697940516?searchId=202308011333480F886C2A2AE1C06DAA0B#comment

我之前一直理解的脚手架就是拉取一份模板项目代码下来,而有难度的脚手架应该是支持扩展的,能够根据用户的选择来构建不同的项目模板。

https://github.com/xun082/react-cli

https://juejin.cn/post/7246001188449550396?share_token=aac06d17-4ce8-429d-b237-63e10991e6cb#comment

脚手架开发

书接上回,这次来做一个脚手架开发,先实现拉去 template 仓库里面的固定代码,如果后续脚手架需要扩展,适配不同的框架和项目,就只需要在 template 里面新建一个分支,每次都去拉取不同的分支代码就可以了。 新的脚手架项目我决定要用 ESlint 来做代码格式化,弃用 Prettier。

  • npm init -y 初始化包

  • package.json 中配置 bin

  • npm install -save-dev typescript @types/node 安装 ts

  • tsc --init 生成 ts 配置文件 ts 的配置 include 和 exclude 配置是用来说明哪些文件需要编译,哪些文件不需要被编译的,比如我这里配置的 include 是 src 下面的文件,那我 src 外的 ts 文件则不会被编译。而如果我不添加 include 配置,则所有的 ts 文件都会被编译

    json
    "include": ["src/**/*"],
    "exclude": ["node_mudules"]
  • npm i -D @antfu/eslint-config eslint vscode默认的保存代码自动格式化:左下角的 setting,搜索 format,勾选 Editor:Format On Save,即可实现保存代码自动格式化,这里的格式化不是按照eslint的规则来格式化的

    eslint 的保存时自动格式化代码,点击左下角的setting打开设置后,点击Open Settings(JSON),在配置文件中添加下面的配置,即可实现vscode按照eslint规则来实现代码格式化

    json
    "eslint.format.enable": true,
    "eslint.run": "onSave",
    "editor.codeActionsOnSave": {
        "source.fixAll": true
    }

    因为我这里使用的是@antfu/eslint-config,所以有些eslint的配置我并不喜欢,需要按照自己的需求做些修改:

    json
    {
        "extends": "@antfu",
        "rules": {
            // 关闭定义变量转为const
            "prefer-const":"off",
            // 保存代码时缩进4个空格
            "indent":["error", 4],
            "@typescript-eslint/indent": ["error", 4],
            // 允许使用console
            "no-console":"off"
        }
    }

    到这里,eslint配置并且保存代码时自动格式化代码已经完成了

  • 使用npm link

这里记录一个模块引入的报错:commander,当我安装了以后,我package.json中有type:module配置,并且tsconfig.json中配置的"module": "esnext",这个时候使用import { Command } from 'commander'引入竟然会报错:Cannot find module ‘commander’. Did you mean to set the ‘moduleResolution’ option to ‘nodenext’, or to add aliases to the ‘paths’ option?ts(2792) 然后我就去tsconfig.json中配置了"moduleResolution": "NodeNext",报错就消失了。这里纠结了ts的配置纠结了很久,一直在想究竟如何才能让ts既可以使用commonjs的包,又可以使用esm的包,最后还是决定使用rollup来对ts进行打包,用@rollup/plugin-commonjs插件来解决这个问题。

取消eslint的报错提示 // eslint-disable-next-line no-self-assign

npm link创建的软连接并不会执行,于是我改用了下面的命令来执行脚手架: node .\lib\index.js init wakk

最后一个问题:npm link为什么不会让命令执行?

ts
#!/usr/bin/env node

打包后的js中如果以这行代码开头,那么npm link后的命令才会用node命令执行。而使用rollup打包以后,这行代码被当作注释删除,所以打包以后的js执行npm link后的命令不会执行。

ts
output: [
    {
        file: './lib/index.js',
        format: 'esm',
        // 添加改行代码到打包文件的开头
        banner: '#!/usr/bin/env node'
    },
],

在rollup的打包配置中加上banner配置即可解决这个问题。