日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端如何搭建一个成熟的脚手架

發布時間:2025/4/16 HTML 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端如何搭建一个成熟的脚手架 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

有了之前的基礎(前端如何搭建一個簡單的腳手架),我們現在可以講講一個成熟的腳手架是怎么做了。

這里我們參考vue-cli的源碼,基于rollup和typescript一步步搭建。vue-cli作為vue的腳手架,給如此多的前端開發者使用,已經算是成熟了吧。

開始

以下我們的命令仍然是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用來開發類庫(簡單易上手,打包后代碼能讀懂,至于其他的特性webpack目前基本已支持)。

現在來明確我們的需求

  • 使用typescript編寫模塊代碼
  • 打包成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腳本命令("scripts"字段)

{ "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 build)到bin文件夾下后,配置一下package.json的bin字段為bin/ds.js,然后發布npm(參考快速發布一個vue-fullpage組件到npm試一下命令。

如果失敗,請重新審視上述之流程。

初始化模板

我們對模板的要求

  • 文件目錄必須含有template文件夾,并且所需模板文件放在該目錄下

  • 可用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 testif(路徑存在){//動態構造模板到你的目錄如testgenerate()}else{//報錯日志}}else{//1.檢查當前process的node版本,大于6才可以用//2.檢查當前package.json的版本,跟遠程倉庫的版本比較一下。如果不一樣,就提醒一下用戶有新版本//3.下載遠程倉庫到本地(本地一般存放用戶目錄里的.ds-template文件夾下),然后執行generate函數} } 復制代碼

動態模板

大家也看到了,其實最重要的就是generate函數~

  • 而如果我們去掉這一步generate模板的話,其實就是相當于下載一個靜態模板,如果我們對于用戶自定義沒要求的話,其實可以跳過這一步。
  • generate函數里面用到了metalsmith,這個就相當于我們之前用的gulp,通過不斷地編寫中間件來優化打包后的結果。
function generate(){const opts = getOptions(name, templatePath) as meta; // 獲取meta.js配置,存到opts里// 我們把所需文件放在源文件的template目錄下,其他一些如測試放在外面。初始化一下metalsmithconst 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語法,作為占位符,我們這里重新渲染模板文件// 源目錄打包到目標目錄tometalsmith.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/#questionname: {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,有以下比較好玩的接口

  • 個人主要信息: api.github.com/users/用戶名
  • 個人所有repo:api.github.com/users/用戶名/r…
  • repo詳細信息:api.github.com/repos/用戶名/倉…
  • issues列表。api.github.com/repos/用戶名/倉…
  • 某條issue詳情:api.github.com/repos/用戶名/倉… issues都是以1,2,3這樣的序列排號的。
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:基于rollup和typescript構建類庫
  • ds-cli-doc-template:基于vuepress的文檔模板

轉載于:https://juejin.im/post/5c98dc71e51d4501806d0a98

總結

以上是生活随笔為你收集整理的前端如何搭建一个成熟的脚手架的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。