zoukankan      html  css  js  c++  java
  • 从npm init vite-app <project-name>学到的知识记录

    起初我想通过create-vite-app创建一个vite的vue项目,一开始使用全局安装create-vite-app的方法:

    npm install -g create-vite-app

    全局安装完之后,我们还需要调指令生成项目:

    create-vite-app viteApp 或者 cva viteApp

    然后我发现create-vite-app在npm官网中安装方法是这样的:

    npm init vite-app <project-name>

    通过这种方法安装,我感觉跟使用npx是一样的效果,都是避免了全局安装,安装完之后直接执行创建项目,也就是一步可以完成,并且不会产生全局安装(都是临时下载安装,安装完后就删除)
    用过create-react-app都知道,目前都推荐使用npx create-react-app 创建react项目,同时也可以使用npm init react-app去创建:

    发现create-vite-app和create-react-app前面都有create,于是去npm包官网查看了npm init的说明:

    * npm init foo -> npx create-foo
    * npm init @usr/foo -> npx @usr/create-foo
    * npm init @usr -> npx @usr/create
    

    所以:npm init vite-app 和npx create-vite-app 是一样的,npm init一个以create-开头的和npx安装是一样的

    我们顺便拓展几个问题点:

    一、全局安装后,为什么可以在cmd下面使用create-vite-app或cva指令?

    答:我们在安装完后,会发现全局包会被安装到这个目录下面:

    C:UsersJ0201AppDataRoaming pm ode_modulescreate-vite-app

    同时在C:UsersJ0201AppDataRoaming pm下面会生成cmd文件:

    node安装后,会默认将C:UsersJ0201AppDataRoaming pm添加至环境变量,如果没有添加成功,就手动修改:

    (如果提示指令找不到,通常是环境变量没设置对)

    有了这个环境变量,就能在cmd下运行当前变量下面的指令,然后按照执行~

    二、create-vite-app和cva是怎么生成的?

    答:我们打开create-vite-app源码(全局安装后在C:UsersJ0201AppDataRoaming pm ode_modulescreate-vite-app这个文件夹下面),看下package.json文件,有个bin字段:

      "bin": {
        "create-vite-app": "index.js",
        "cva": "index.js"
      },
    

    会根据bin字段下的属性生产对应的指令,同时执行指令会执行对应的js,也就是index.js:

    同时,index.js首行需要加上,也就是如果该文件作为cmd下运行的文件,需要加上这一段在首行:

    #!/usr/bin/env node

    三、为何npm init vite-app 和npx create-react-app 不需要执行?

    答:这个问题其实很简单,在npm官网有说明:

    [https://docs.npmjs.com/cli/v6/commands/npm-init](npm init)

    initializer in this case is an npm package named create-<initializer>, which will be installed by npx,
    and then have its main bin executed -- presumably creating or updating package.json
    and running any other initialization-related operations.
    
    

    也就是安装完后,对应的package.json中的bin对应的脚本会被执行。

    四、学习下create-vite-app中的index.js

    注释是个人理解加的,非尤大写的(万一哪里说的不对,不能污蔑尤大[哭笑])

    #!/usr/bin/env node
    const path = require('path')
    const fs = require('fs-extra')
    /**
     * process.argv获取到的是一个地址数组,第3项也就是我们前面指令中创建的projectName
     * 通过minimist,argv变量存储的是一个对象,如果没有传-t/-template字段,里面就只有一个属性'_',值是对应的projectName:({ _: projectName })
     * -t/-template是通过指令中传进来的,后面对对应的模板名,templateDir会根据值返回对应的模板,也就是cva viteApp -t vue-ts
     */
    const argv = require('minimist')(process.argv.slice(2))
    
    async function init() {
      const targetDir = argv._[0] || '.'
      const cwd = process.cwd()
      const root = path.join(cwd, targetDir)
      const renameFiles = {
        _gitignore: '.gitignore',
      }
      console.log(`Scaffolding project in ${root}...`)
    
      /**
       * ensureDir这个是fs创建文件夹,我们在D:根目录下创建,对应的root就是D:/projectNam
       * 如果我们不传projectName,根目录下,root就是D:,fs.ensureDir(root)会返回失败,往下便不再执行。如果不是根目录,则existing长度不为0,表示已经存在该目录,输出Error: target directory is not empty,并退出程序
       * 如果传入的projectName已存在,则existing长度不为0,表示已经存在该目录,输出Error: target directory is not empty,并退出程序
       */
      await fs.ensureDir(root)
      const existing = await fs.readdir(root)
      if (existing.length) {
        console.error(`Error: target directory is not empty.`)
        process.exit(1)
      }
    
      /**
       * 往下执行完便成功,会生成模板,并输出相应的console.log
       */
    
      const templateDir = path.join(
        __dirname,
        `template-${argv.t || argv.template || 'vue'}`
      )
      const write = async (file, content) => {
        const targetPath = renameFiles[file]
          ? path.join(root, renameFiles[file])
          : path.join(root, file)
        if (content) {
          await fs.writeFile(targetPath, content)
        } else {
          await fs.copy(path.join(templateDir, file), targetPath)
        }
      }
    
      const files = await fs.readdir(templateDir)
      for (const file of files.filter((f) => f !== 'package.json')) {
        await write(file)
      }
    
      const pkg = require(path.join(templateDir, `package.json`))
      pkg.name = path.basename(root)
      await write('package.json', JSON.stringify(pkg, null, 2))
    
      console.log(`
    Done. Now run:
    `)
      if (root !== cwd) {
        console.log(`  cd ${path.relative(cwd, root)}`)
      }
      console.log(`  npm install (or \`yarn\`)`)
      console.log(`  npm run dev (or \`yarn dev\`)`)
      console.log()
    }
    
    init().catch((e) => {
      console.error(e)
    })
    
    

    五、我们会了这个,对我们有什么用,如何学以致用?

    答:最近想做一个模板生成器,也就是使用命令生成vue的页面模板,生成后简单修改下配置,便是我们的完整页面,这样在团队协助中,能够加快开发速度。我觉得可以使用bin脚本去执行,通过生成cmd指令,执行指令后,结合模板生成器的代码,输出相应的页面。
    如果公司有条件搭建了属于公司自己的私库,我们可以学习create-vite-app的做法,创建以create-开头的包,并上传到私库,然后全局安装也好,npm init/npx也好,就可以像create-vite-app一样,直接调用bin中的指令执行。
    如果没有私库,代码不担心公开问题可以放npm官网。不行的话可以在当前包下面使用npm link,生成全局命令。npm link后,会把当前的包安装到全局AppDataRoaming pm下,同时也会生成bin中的指令,在AppDataRoaming pm当前包是以快捷方式的形式直接访问的,所以修改的时候,全局也会跟着修改。比较适合开发的时候。

    这一步,我后面会做个简单的demo后会再记录一下。

    六、拓展什么是npx和vite

    npx推荐阮一峰的[http://www.ruanyifeng.com/blog/2019/02/npx.html](npm 使用教程)

    最重要两点:

    1. 调用项目安装的模块
    2. 避免全局安装模块

    什么是vite:

    作者原话: Vite,一个基于浏览器原生 ES Modules 的开发服务器。利用浏览器去解析模块,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。

    Vite(读音类似于[weɪt],法语,快的意思) 是一个由原生 ES Module 驱动的 Web 开发构建工具。在开发环境下基于浏览器原生 ES imports 开发,在生产环境下基于 Rollup 打包。

    Vite的特点:

    • Lightning fast cold server start - 闪电般的冷启动速度
    • Instant hot module replacement (HMR) - 即时热模块更换(热更新)
    • True on-demand compilation - 真正的按需编译

    为了实现上述特点,Vite 要求项目完全由 ES Module 模块组成,common.js 模块不能直接在 Vite 上使用。因此不能直接在生产环境使用。在打包上依旧还是使用 rollup 等传统打包工具。因此 Vite 目前更像是一个类似于 webpack-dev-server 的开发工具.

  • 相关阅读:
    ms08-067
    siem主流厂商
    技术设计
    SOC
    通过 IDE 向 Storm 集群远程提交 topology
    Storm
    java线程中Exchanger使用
    android笔记
    学习笔记 Java类的封装、继承和多态 2014.7.10
    POJ 2533 Longest Ordered Subsequence DP
  • 原文地址:https://www.cnblogs.com/wuzhiquan/p/14183341.html
Copyright © 2011-2022 走看看