前端持续集成学习(未完待续)

430 阅读2分钟

一、CI 与 CD

持续集成CI:Continuous integration

CI

持续交付CD:Continuous delivery

CD

二、资源定位引发的一系列问题

假设我们现在线上有 index.html 以及 a.cssb.css,我们需要修改 a.css

  1. 第一个版本的修改是把所有的css文件都加上一个版本戳 href="a.css?v1421et",但是这样会把用户缓存的好好的b.css的也改了。
  2. 第二个版本是干脆把a.css文件名改成v1421et.css,每一个css文件都有自己的MD5,用哪个css就换哪个。但是如果html文件和css文件都要换的话,由于两个问价送到服务器的时间会要延迟,用户端可能会出现html文件到了,css文件没到的报错现象。
  3. 最终的解决方案,不采用css文件替换的方法了,而采用永久在服务器保留css文件的方法,每次先去把一个新命名的css文件扔到服务器,再去更换html。

三、发布自己的脚手架

建立目录结构 ./shiyu/bin,根目录执行 npm init -y,添加"bin"的相关命令如下:

{
  "name": "shiyu",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "bin": {
    "shiyu": "./bin/shiyu"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

bin文件夹下建立shiyu文件后,执行sudo npm link把命令暴露到全局

#!/usr/bin/env node

console.log("痛苦时,等待和希望!");

#!Shebang 又称 Hashbang这个符号通常在Unix系统的基本中第一行开头中出现,用于指明这个脚本文件的解释程序。

引入 commander给用户反馈信息的包, @darkobits/lolcatjs用来美化字体的包,以及ASCLL文字生成网站

#!/usr/bin/env node
const program = require("commander");
const Printer = require("@darkobits/lolcatjs");
const str =
    ":'######::'##::::'##:'####:'##:::'##:'##::::'##:\n" +
    "'##... ##: ##:::: ##:. ##::. ##:'##:: ##:::: ##:\n" +
    " ##:::..:: ##:::: ##:: ##:::. ####::: ##:::: ##:\n" +
    ". ######:: #########:: ##::::. ##:::: ##:::: ##:\n" +
    ":..... ##: ##.... ##:: ##::::: ##:::: ##:::: ##:\n" +
    "'##::: ##: ##:::: ##:: ##::::: ##:::: ##:::: ##:\n" +
    ". ######:: ##:::: ##:'####:::: ##::::. #######::\n" +
    ":......:::..:::::..::....:::::..::::::.......:::\n" +
    "世玉的脚手架";
program.version(Printer.default.fromString(str), "-v,--version");
program.parse(process.argv);

注意!一定要program.parse(process.argv);

引入 chalk用来美化给用户反馈信息的包以及类似 json2ts的作为讲解实例的 json => typescript 的包。

#!/usr/bin/env node
const program = require("commander");
const Printer = require("@darkobits/lolcatjs");
const chalk = require("chalk");
const inquirer = require("inquirer");
const str =
    ":'######::'##::::'##:'####:'##:::'##:'##::::'##:\n" +
    "'##... ##: ##:::: ##:. ##::. ##:'##:: ##:::: ##:\n" +
    " ##:::..:: ##:::: ##:: ##:::. ####::: ##:::: ##:\n" +
    ". ######:: #########:: ##::::. ##:::: ##:::: ##:\n" +
    ":..... ##: ##.... ##:: ##::::: ##:::: ##:::: ##:\n" +
    "'##::: ##: ##:::: ##:: ##::::: ##:::: ##:::: ##:\n" +
    ". ######:: ##:::: ##:'####:::: ##::::. #######::\n" +
    ":......:::..:::::..::....:::::..::::::.......:::\n" +
    "世玉的脚手架";
const bindHandler = {
    init() {
        const json2ts = require("json2ts");
        const shiyuJson = {
            shiyu: "世玉",
            data: {
                age: 23,
                like: ["girl", "pretty"]
            }
        };
        const jsonContent = JSON.stringify(shiyuJson);
        const res = json2ts.convert(jsonContent);
        console.log(res)
    }
};

program.version(Printer.default.fromString(str), "-v,--version");
program.option("-i,--init", "项目初始化🐼");
program
    .usage("<cmd> [options]")
    .arguments("<cmd> [env]")
    .action((cmd, otherParams) => {
        const handler = bindHandler[cmd];
        if (typeof handler === "undefined") {
            console.error(chalk.red(`非常遗憾😄[${cmd}]😄命令还不支持`));
            process.exit(1);
        } else {
            handler(otherParams);
        }
    });
program.parse(process.argv);

.usage("<cmd> [options]") :用法,.arguments("<cmd> [env]"):参数,process.exit(1)退出 cmd

引入inquirer给用户反馈yes/no的信息包, shelljs 进行shell操作的包, userHome 根目录pwd的包, ora loading的包

#!/usr/bin/env node
const program = require("commander");
const Printer = require("@darkobits/lolcatjs");
const chalk = require("chalk");
const inquirer = require("inquirer");
const shelljs = require("shelljs");
const userHome = require("user-home");
const ora = require("ora");
const str =
    ":'######::'##::::'##:'####:'##:::'##:'##::::'##:\n" +
    "'##... ##: ##:::: ##:. ##::. ##:'##:: ##:::: ##:\n" +
    " ##:::..:: ##:::: ##:: ##:::. ####::: ##:::: ##:\n" +
    ". ######:: #########:: ##::::. ##:::: ##:::: ##:\n" +
    ":..... ##: ##.... ##:: ##::::: ##:::: ##:::: ##:\n" +
    "'##::: ##: ##:::: ##:: ##::::: ##:::: ##:::: ##:\n" +
    ". ######:: ##:::: ##:'####:::: ##::::. #######::\n" +
    ":......:::..:::::..::....:::::..::::::.......:::\n" +
    "世玉的脚手架";
const bindHandler = {
    init() {
        inquirer
            .prompt([
                {
                    type: "test",
                    message: "一、用户请输入文件夹名称:",
                    name: "dirname"
                }
            ])
            .then(answers => {
                const {dirname} = answers;
                shelljs.cd(`${userHome}/Desktop`);
                const spinner = ora(" 正在下载。。。");
                spinner.start();
                shelljs.mkdir(dirname)
            })
    }
};

program.version(Printer.default.fromString(str), "-v,--version");
program.option("-i,--init", "项目初始化🐼");
program
    .usage("<cmd> [options]")
    .arguments("<cmd> [env]")
    .action((cmd, otherParams) => {
        const handler = bindHandler[cmd];
        if (typeof handler === "undefined") {
            console.error(chalk.red(`非常遗憾😄[${cmd}]😄命令还不支持`));
            process.exit(1);
        } else {
            handler(otherParams);
        }
    });
program.parse(process.argv);