zoukankan      html  css  js  c++  java
  • egg源码浅析一npm init egg --type=simple

    要egg文档最开始的时候,有这样的几条命令:

    我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目:
    $ mkdir egg-example && cd egg-example
    $ npm init egg --type=simple
    $ npm i

    其中的 npm init egg --type=simple 命令为什么能够生成egg项目的基本构架呢?

    一、npm init命令

    根据 https://www.npmjs.cn/cli/init/ 官网的解释:

    npm init <initializer> can be used to set up a new or existing npm package.

    initializer in this case is an npm package named create-<initializer>, which will be installed by npx, and then have its main bin executed.

      按照上面的解释,npm init egg 相当于 npx create-egg 并且执行create-egg的bin.

    二、npx命令

      npx相当于npm,但npx会把node_modules/.bin/目录加入环境变量. 

      这里讲怎么用:http://www.ruanyifeng.com/blog/2019/02/npx.html

    也就是说,npm init egg 相当于执行 npx create-egg,而npx create-egg命令会下载create-egg库,再执行里面的bin(package.json里的bin字段)。

      另外,npx create-egg 会在当前目录/node_modules目录下查找有没有create-egg,没有就会下载到临时目录,最后删除。

    三、下载create-egg库

      create-egg的目录结构如下,package.json里没有main,却有bin字段,bin字段值是./bin/create-egg.js。当安装create-egg的时,会在当前安装目录下的node_modules/.bin/目录放置create-egg作为可执行文件。

      

      create-egg.js文件里只有一行代码:

    console.log('--------i am create-egg');
    require('egg-init/bin/egg-init');

      再来看egg-init库。

    四、egg-init

    #!/usr/bin/env node
    'use strict';
    const co = require('co');
    const Command = require('..');
    
    co(function* () {
      console.log('process.cwd:', process.cwd());
      console.log('process.argv.slice:', process.argv.slice(2));
      // process.cwd: /Users/demon/Desktop/test/createeggtest
      // process.argv.slice: [ '--type=simple' ]
      yield new Command().run(process.cwd(), process.argv.slice(2));
    }).catch(err => {
      console.error(err.stack);
      process.exit(1);
    });

    process.cwd是命令执行的所有文件夹,argv.slice(2)之后是--type=simple字符串。

    之后,向 https://registry.npmjs.org/egg-init-config/latest请求,获取响应:

    {
        "name":"egg-init-config",
        "version":"1.5.0",
        "description":"egg init boilerplate config",
        "config":{
            "boilerplate":{
                "simple":{
                    "package":"egg-boilerplate-simple",
                    "description":"Simple egg app boilerplate"
                },
                "microservice":{
                    "package":"egg-boilerplate-microservice",
                    "description":"Microservice app boilerplate based on egg"
                },
                "sequelize":{
                    "package":"egg-boilerplate-sequelize",
                    "description":"egg app with sequelize"
                },
                "ts":{
                    "package":"egg-boilerplate-ts",
                    "description":"Simple egg && typescript app boilerplate"
                },
                "empty":{
                    "package":"egg-boilerplate-empty",
                    "description":"Empty egg app boilerplate"
                },
                "plugin":{
                    "package":"egg-boilerplate-plugin",
                    "description":"egg plugin boilerplate"
                },
                "framework":{
                    "package":"egg-boilerplate-framework",
                    "description":"egg framework boilerplate"
                }
            }
        },
        ...
    }

    根据得到的响应,匹配--type=simple,得到package:

    "simple":{
        "package":"egg-boilerplate-simple",
        "description":"Simple egg app boilerplate"
    },

    得到egg-boilerplate-simple,再次向 https://registry.npmjs.org/egg-boilerplate-simple/latest请求,

    {
      "name": "egg-boilerplate-simple",
      "version": "3.3.1",
      ...
    "dist": { "integrity": "sha512-zj8ES0n7lAXGMWornOOY1n0Q+skX0wA9hjl40QsTa3SS5FcExVoEWQ52kCeT+bnvNKEL8fiOD9S2J4J9wDjbKg==", "shasum": "c56c87c1f2b705a9247b0903958aac76d141b2c6", "tarball": "https://registry.npmjs.org/egg-boilerplate-simple/-/egg-boilerplate-simple-3.3.1.tgz", "fileCount": 31, "unpackedSize": 19461, "npm-signature": "-----BEGIN PGP SIGNATURE----- Version: OpenPGP.js v3.0.4 Comment: https://openpgpjs.org wsFcBAEBCAAQBQJcv91nCRA9TVsSAnZWagAAyZ8P/RyW3+wL32xjrVTDNDlQ BuxafQ/J5gGtG3tlwkqG184G3hSoceY0qSiIKv60sVsOtMZfJUZd5znNAGro /pSmKW23jfA1Xw49HGMfT++6ZQ+PoZ8l13p5zwjIHs10+d/RAx1hi3xm6xiA TjfKQXCUbt7aLYGQgpX155ZD/DcvI+VUWTw6fc5pJg7NXkOFDSwo+TaxsxHX w7iom89bQICaK6mBybDMI2+gkeMvSuKPnBiI8TuSCrgoGnkfXWF6Hd6ZL76O G3uA2LqYNqELUsPyoD97NL17vOayGbP8xJdn+l9dUQF8e4oD9m6gjEz0uTKO r3zxjx8X8HrjaJo2CJbYrOl5+zNYrM4dTt/oY5zU56aoOesCcht8FxrcaHNl /fVxIH8YgUzv3ZbwGRAb5G/NwF5GwtfmyGtkiJ/9i5awB+QLezC7Hkl4ZMGZ nblIDGnPGF+zY7Epg2FPDQgB/SDurENiAFiSPBX7jbi3AH9hfABHeH4NeYTi 5j+NGtv2QY6eqffxrQpg7Vibe5nbRKCPkLqcqy0BsPixSHe7RvnNMulxX609 JUCrz5M9YNQEAkDckomD5QDzWzTFaPEWqUUjohfgPheIi2KJ9w0jU2QV6pxG h3MbZNyLYHw1cXUEkupiNqSVwP7NGbDcH5t5uQGrSS4j4RdpxrSonNaB0You Zdaq =Q83Q -----END PGP SIGNATURE----- " },   ... }

    拿到dist.tarball字段的值,下载到临时目录下的egg-init-boilerplate目录并解压:

    const saveDir = path.join(os.tmpdir(), 'egg-init-boilerplate');
      yield compressing.tgz.uncompress(response.res, saveDir);

    之后,进入saveDir/package/boilerplate目录,boilerplate目录内容如下

    之后就是把这个目录的内容拷贝到目标目录下,当然会把_前缀去掉:

    const to = path.join(targetDir, this.replaceTemplate(this.fileMapping[file] || file, locals));
    const content = fs.readFileSync(from);
    this.log('write to %s', to);
    
    // check if content is a text file
    const result = isTextOrBinary.isTextSync(from, content)
       ? this.replaceTemplate(content.toString('utf8'), locals)
       : content;
    
    mkdirp.sync(path.dirname(to));
    fs.writeFileSync(to, result);

    这就是npm init egg --type=simple内容的由来了。 

     
     
  • 相关阅读:
    详解javascript实现自定义事件
    详谈LABJS按需动态加载js文件
    SeaJS入门教程系列之SeaJS介绍(一)
    Underscore.js 入门
    Underscore.js (1.7.0)-集合(Collections)(25)
    Underscore.js (1.7.0)-函数预览
    js/jquery判断浏览器的方法小结
    ParNew收集器
    CMS(Concurrent Mark-Sweep)
    java集合类深入分析之Queue篇(Q,DQ)
  • 原文地址:https://www.cnblogs.com/cool-fire/p/11007329.html
Copyright © 2011-2022 走看看