Как построить зрелые леса в передней части

Vue.js

предисловие

С предыдущей основой (Как построить простые леса в передней части), теперь можно говорить о том, как делаются полноценные строительные леса.

Здесь мы обращаемся к исходному коду vue-cli и создаем его шаг за шагом на основе свертки и машинописного текста. В качестве каркаса vue, vue-cli используется очень многими фронтенд-разработчиками, он уже зрелый.

Начинать

Следование нашей команде по-прежнемуds~, шаблонds-cli-lib-template

Структура каталогов

├─ bin            # 打包文件目录
│  ├─ ds.js       # package.json里的bin字段引用文件 
├─ src
│  ├─ lib         # 具体命令目录
│     ├─ list     # ds list
│     ├─ init     # ds init
│  ├─ utils       # 工具函数
├─ main.ts        # 入口文件
├─ typings        # typescript类型文件目录
├─ rullup.config.js # rollpu构建配置
├── test            #  测试用例

Написать конфигурацию сборки

Сегодня webpack используется для разработки приложений (горячее обновление hmr, разделение кода и т. д.), а rollup — для разработки библиотек классов (простой и удобный в использовании, код можно прочитать после упаковки, а другие функции в основном поддерживаются вебпак).

Теперь, чтобы уточнить наши потребности

  • написать код модуля, используя машинописный текст
  • Код упакован в спецификацию модуля umd
  • Пакеты, которые могут ссылаться на спецификацию commonjs (большинство пакетов не являются спецификацией модулей ES по историческим причинам)
  • Сжимайте и упаковывайте код, чтобы уменьшить размер
//rollup.config.js
import typescript from "rollup-plugin-typescript2";
import commonjs from 'rollup-plugin-commonjs'
import { uglify } from 'rollup-plugin-uglify'
export default {
    //入口文件
  input: "src/main.ts",
  output: [
    {
      banner: "#!/usr/bin/env node",
      /**
       * 头部插入这段代码
       * */
      name: "ds",
      file: "bin/ds.js",
      //打包成umd模块规范
      format: "umd"
    }
  ],
  plugins: [
    typescript(),
    commonjs({
      include: "node_modules/**",
      extensions: ['.js', '.ts']
    }),
    uglify()
  ],
};

Команда сценария npm (поле «скрипты»)

{
"clean": "rm -rf ./bin && mkdir bin",
"build": "npm run clean && rollup --config"
}

записать входной файл

Это очень простые вещи, и мы, как правило, не помещаем очень сложную логику в входной файл.

const cmd = require('commander');
const config = require('../package.json');

//这里cli-init.ts和cli-list.ts我们可以简单导出一个函数,如
// export default function(...args) {
//     console.log('init')
// }
import init from './lib/init/cli-init'; 
import list from './lib/list/cli-list';

const command= {
    init,
    list
};

//map对应的type,从而执行
function exec(type, ...args) {
    config.debug = args[0].debug;
    command[type](...args);
}

cmd
  .usage('<command>')
  .version(config.version)
  .description('欢迎使用ds-cli');

cmd
  .command('init')
  .description('初始化组件模板')
  .action((...args) => exec('init', ...args));

cmd
  .command('list')
  .description('查看线上组件模板')
  .action((...args) => exec('list', ...args));

cmd.command('help')
  .description('查看帮助')
  .action(() => cmd.help());

// 解析输入的参数
cmd.parse(process.argv);
if (!cmd.args.length) {

  cmd.help();
}

После того, как мы упакуем (выполним сборку npm run) в папку bin, настроим поле bin package.json как bin/ds.js, а затем опубликуем npm (см.Быстро опубликуйте компонент vue-fullpage в npmПопробуйте команду.

Если это не удается, повторите описанный выше процесс.

шаблон инициализации

Наши требования к шаблонам

  • Каталог файлов должен содержать папку шаблона, и необходимые файлы шаблона помещаются в этот каталог.

  • Расширенная настройка с помощью meta.js (так называемые динамические шаблоны)
  • Соглашение об именах файлов шаблонов — ds-cli-'name'-template, что удобно для создания шаблонов для извлечения.
  • Вам не нужно использовать онлайн-шаблон. Если есть локальный шаблон, вы можете использовать его напрямую. Если это онлайн-шаблон, его следует загрузить в каталог .ds-templates локального каталога пользователя (~/.ds-templates).

ожидать команду

ds init <template-name> <app-name> #模板名字和应用名字

Процесс и логика

if(当前目录下构建){
    询问一下是不是当前目录,是的话进入run函数
}else{
    进入主流程run函数
}
//run函数
function run(){
    if(模板路径是本地文件路径){
        //支持本地模板如ds init /usr/webpack test
        if(路径存在){
            //动态构造模板到你的目录如test
            generate()
        }else{
            //报错日志
        }
    }else{
        //1.检查当前process的node版本,大于6才可以用
        //2.检查当前package.json的版本,跟远程仓库的版本比较一下。如果不一样,就提醒一下用户有新版本
        //3.下载远程仓库到本地(本地一般存放用户目录里的.ds-template文件夹下),然后执行generate函数
    }
}

Динамический шаблон

Вы можете видеть, что на самом деле самая важная вещь — это функция генерации~

  • И если мы удалим шаблон генерации на этом шаге, это фактически эквивалентно загрузкестатический шаблон, если нам не требуется пользовательская настройка, мы можем пропустить этот шаг.
  • используется в функции генерацииmetalsmith, который эквивалентен gulp, который мы использовали ранее, который оптимизирует упакованные результаты за счет постоянного написания промежуточного программного обеспечения.
function generate(){
    const opts = getOptions(name, templatePath) as meta;  // 获取meta.js配置,存到opts里
    // 我们把所需文件放在源文件的template目录下,其他一些如测试放在外面。初始化一下metalsmith
    const metalsmith = Metalsmith(path.join(templatePath, 'template')) //我们约定,将模板所有文件放在ds-cli-lib-template/template里
    //中间件
     metalsmith.use(askQuestions(opts.prompts))  // 询问问题,将信息存metalsmith.metadata()
    .use(filterFiles(opts.filters))  // 通过问题交互过滤掉不需要的文件
    .use(renderTemplateFiles()); // 模板里面可以使用handlebar语法,作为占位符,我们这里重新渲染模板文件

    // 源目录打包到目标目录to
    metalsmith.clean(false)
    .source('.') 
    .destination(to)
    .build((err, files) => {
      done(err);
    });
}
  • Мы в шаблоне (типаds-cli-lib-template) необходимо создать meta.js для настройки нужных нам полей.
module.exports={
    //会通过中间件把这些字段存在metalsmith.metadata(),方便接下来的中间件调用
    prompts:{
        //格式可以参考https://github.com/SBoudrias/Inquirer.js/#question
        name: {
            type: 'string',
            required: true,
            message: 'Project name',
        },
        author: {
            type: 'string',
            message: 'Author',
        },
        description: {
            type: 'string',
            required: false,
            message: 'Project description',
            default: '构建一个lib',
        },
        lint: {
            "type": "confirm",
            "message": "是否用tslint"
        },
    },
    
    filters: {
        //当上面prompts的lint为false的时候,就过滤掉文件
        "tslint.json": "lint",
        "tsconfig.json": "lint"
    }
}

До сих пор здесь мы объясняли основные принципы, вы должны уметь создавать леса и шаблоны, подходящие для вашей команды.

Список репозиториев шаблонов

В общем, будет команда list

Спасибо github за предоставленный нам API, есть следующие интересные интерфейсы


const logSymbols = require('log-symbols');
const chalk = require('chalk');


export default async function(...args) {

    // 获取仓库列表
    const res=await request({
        url: 'https://api.github.com/users/yokiyokiyoki/repos',
        method: 'GET'
        }
    );
    let list;
    if(res.status===200) {
        console.log(logSymbols.info,chalk.green('共有下列模板'));
        list=res.data.filter((item)=> {
            return item.name.includes('ds-cli')&&item.name.includes('template');
        }).forEach(item=> {
            console.log();
            console.log(chalk.green(item.name));
        });
    } else {
        console.log(logSymbols.error,`获取仓库列表失败${res.data}`);
    }
}

Следует отметить, что иногда github исчерпан, и запрос будет медленнее, что не очень удобно для пользователя (пробовал несколько раз)ds listЕсли будет медленно, разработчик потеряет терпение).

Если вы стремитесь к пользовательскому опыту, вот идея, которая заключается в кэшировании. Результат можно записать в файл, закешировать в папку, где шаблон хранится локально (~/.ds-templates), а также включить время запроса (в основном используется для определения, сегодня ли он), и тогда мы судим в коде Проверить: Когда будете запрашивать в следующий раз, есть ли файл локально, и если да, то прочтите его.Прочитав его, оцените, отличается ли время в нем на один день от текущего времени, и повторно запросите после на следующий день (интервал времени контролируете сами), прикрывая исходный файл кеша.

Ссылаться на

  • ds-cli: Текущие временные команды включают init и list (чтобы получить список всех шаблонов), с подробными комментариями, я вас не понимаю! ! !
  • ds-cli-lib-template: Создайте библиотеку классов на основе свертки и машинописного текста.
  • ds-cli-doc-template: шаблон документа на основе vuepress