最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • npm init @vitejs/app 到底干了什么

    正文概述 掘金(VANTOP前端团队)   2021-04-08   999

    npm init @vitejs/app 到底干了什么

    背景

    最近在闲暇时间学习尤大大的新框架 ViteJs 的时候发现,创建一个新的基于 Vite 的项目时,使用的命令方式是:

    npm init @vitejs/app
    

    这跟我们熟悉的 CLI 创建 Vue 项目的命令完全不一样:

    vue create project-name
    

    「在不安装脚手架工具的情况下,还能直接使用 npm 创建项目?」带着好奇心小小的探究了一下。

    首先我们要知道这个命令 npm init @vitejs/app 是要做什么?

    一番谷歌 + 官网文档,实际上这个命令就是要创建一个新的 Vite 项目,且基于某个模版,这个模版可以是 Vue / React 或其它。那么它到底是如何创建的?带着这个问题我们先来重温下 npm init

    复习 npm init

    npm init 对于我们来说应该非常熟悉了,通常我们使用 npm init 初始化一个 package.json 文件来起手一个项目。大多数小伙伴只用到这,但是这个命令后面是可以携带参数的?这个参数能干什么呢?对于我这见惯大场面的 cv 程序员来说,翻手就是一个谷歌。谷歌大佬告诉我们 npm-init:

    initializer 在这里是一个名为 create-<initializer> 的 npm 软件包,该软件包将由 npx 来安装,然后执行其 package.json 中 bin 属性对应的脚本,会创建或更新 package.json 并运行一些与初始化相关的操作。

    官方说明也给出了命令相对应的一些示例:

    命令等同
    npm init foonpx create-foonpm init @usr/foonpx @usr/create-foonpm init @usrnpx @usr/create

    文章开头的命令 npm init @vitejs/app 正好匹配到了第二条示例,对应起来应该是这样:

    npm init @vitejs/app -> npx @vitejs/create-app
    

    从上面的解释可以看出,在命令行中运行 npm init @vitejs/app,实际上是通过了 npx 运行了名为 @vitejs/create-app 这个包,那么我们就去 Vite 官方仓库找一找有没有叫 create-app 的文件?

    查看 ViteJs 源码发现 packages 文件夹中确实存在一个 create-app 目录,那我们就再深入的看看这个目录里面有什么?

    npm init @vitejs/app 到底干了什么

    @vitejs/create-app 项目做了什么?

    在 create-app 文件夹下的 package.json 中发现 bin 入口:

    {
      "name": "@vitejs/create-app",
      // ...没错了,就是这
      "bin": {
        "create-app": "index.js",
        "cva": "index.js"
      },
    }
    

    bin 属性配置了 create-app 的执行入口文件 index.js ,那我们就去看看 index.js 中做了什么操作,源码过长,部分精简以便享用,感兴趣的小伙伴可深挖:

    // https://github.com/vitejs/vite/blob/main/packages/create-app/index.js
    
    // 省略非关键代码
    const TEMPLATES = [
      yellow('vanilla'),
      green('vue'),
      green('vue-ts'),
      //...
    ]
    
    async function init() {
      let targetDir = argv._[0]
      if (!targetDir) {
        // 第一步:确定用户录入的 Project name
        const { name } = await prompt({
          type: 'input',
          name: 'name',
          message: `Project name:`,
          initial: 'vite-project'
        })
        targetDir = name
      }
    
      const root = path.join(cwd, targetDir)
      console.log(`\nScaffolding project in ${root}...`)
      
      // 第二步:检查是否存在同名目录且是否为空目录
      if (!fs.existsSync(root)) {
        fs.mkdirSync(root, { recursive: true })
      } else {
        const existing = fs.readdirSync(root)
        if (existing.length) {
            //...
        }
      }
    
      // 第三步 校验并选择模版
      let template = argv.t || argv.template
      let message = 'Select a template:'
      if (!template || !isValidTemplate) {
        const { t } = await prompt({
          type: 'select',
          name: 't',
          message,
          choices: TEMPLATES
        })
        template = stripColors(t)
      }
    
      const templateDir = path.join(__dirname, `template-${template}`)
    
      const write = (file, content) => {
        const targetPath = renameFiles[file]
          ? path.join(root, renameFiles[file])
          : path.join(root, file)
        if (content) {
          fs.writeFileSync(targetPath, content)
        } else {
          copy(path.join(templateDir, file), targetPath)
        }
      }
      // 第四步:拷贝并写入文件
      const files = fs.readdirSync(templateDir)
      for (const file of files.filter((f) => f !== 'package.json')) {
        write(file)
      }
    
      const pkg = require(path.join(templateDir, `package.json`))
    
      // 第五步:拷贝 package.json 提示安装运行
      write('package.json', JSON.stringify(pkg, null, 2))
      // ...提示 `npm install / npm run dev`
    }
    
    // 省略功能函数...
    init().catch((e) => {
      console.error(e)
    })
    

    上面的代码主要逻辑如下:

    • 第一步:确定 Project name ,用户输入或默认;
    • 第二步:检查本地是否存在同名目录,并判断是否为空目录;
    • 第三步:选择要创建的模板,vue、vue-ts、react 等;
    • 第四部(核心):根据选择的模板匹配到项目下以 template- 开头的目录,将目录中的所有文件拷贝到本地项目目录中;
    • 第五步:拷贝修改完 name 的新 package.json 到新项目中,并提示安装依赖和运行;

    到此我们已经搞清楚 npm init @vitejs/app 背后是通过执行 create-app 中 bin 所指定的脚本文件。而这个脚本文件(这里是 index.js)所做的工作,就是根据一些配置和模版项目,利用 node 将所有模版文件拷贝到本地项目目录中,从而完成了一个根据模板创建项目的系列操作。

    创建项目可用 CLI 脚手架,为何要如此大费周章呢?莫急且看。

    npm init VS vue create

    我们使用 vue create 来创建项目时,背后是 Vue-CLI 给予我们的能力。所以我们得首先安装 Vue-Cli,然后才可以使用它来创建项目。而 npm init 则跳过了 CLI 这部分,它基于指定脚本来实现,所以与 vue create 对比,它的优点:

    • 项目即工具,更加简单直接;
    • 不用安装额外的 CLI 工具,多一个工具就多一个使用成本;
    • 更新方便,无需同时维护模板和 CLI 工具;

    所以,总的来说使用 npm init 创建项目更加简单和纯粹。

    加深 package.json 认识

    不难发现,create-app 入口文件关键是 package.json 文件的 bin 属性,那么 bin 和 main 有什么区别呢?

    mainbin
    属性是一个 module ID,是程序的主要的入口点,当然如果不设置,默认值就是 index.js如果此 npm 包带有 bin 属性,那么此 npm 包的可执行文件就会被链接到当前项目的 ./node_modules/.bin 中,此后在命令行中就很方便的执行这个包,比如:node node_modules/.bin/myapp,更加详细的解释可参照 package.json bin

    不得不说,package.json 中每个属性都有它的用处,只有仔细的阅读和分析其的含义和用法,才会有创造轮子的那点灵光啊!

    学完能做什么?

    公司新的项目层出不穷,目前项目还在做微前端的重构,微前端中的各个子模块都需要使用一个模板 Ctrl + C / Ctrl + V 来创建,虽然对于我们 cv 程序员来说是小 case,但是如果我们有了自己的 create-app,我们翻手一个 npm init @company/app,岂不更美哉?

    不单如此,我们还可以建立公司内部或对外的模板库项目,将所有常用的模板项目维护到一个项目中,统一维护管理,岂不快哉?(坑已挖好,活已安排,下次一定)...

    以上便是本次分享的全部内容,希望对你有所帮助 ^_^

    喜欢的话别忘了动动手指,点赞、收藏、关注三连一波带走。


    关于我们

    我们是万拓科创前端团队,左手组件库,右手工具库,各种技术野蛮生长。

    一个人跑得快,不如一群人跑得远。欢迎加入我们的小分队,牛年牛气轰轰往前冲。


    起源地下载网 » npm init @vitejs/app 到底干了什么

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元