最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

開發(fā)Node CLI構(gòu)建微信小程序腳手架的示例

 更新時間:2020年03月27日 14:38:34   作者:夏天Summer  
這篇文章主要介紹了開發(fā)Node CLI構(gòu)建微信小程序腳手架,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

本文介紹了 Node CLI 構(gòu)建微信小程序腳手架的示例,分享給大家,具體如下:

 

 

目的

由于目前公司的 TOC 產(chǎn)品只要是微信小程序,而且隨著業(yè)務(wù)的擴展, 會有更多的需求,創(chuàng)建更多的小程序,為了讓團(tuán)隊避免每次開發(fā)前花費大量時間做比如工程化的一些配置,以及保持每個項目的一致性, 所以決定做一個 Node CLI 來創(chuàng)建微信小程序腳手架

  • 節(jié)省開發(fā)前期的大量時間,新項目可以很快開始業(yè)務(wù)開發(fā)
  • 保證項目統(tǒng)一性,有利于團(tuán)隊間的協(xié)作及工程化
  • 提升團(tuán)隊基建意識,從枯燥無味的業(yè)務(wù)開發(fā)中脫離出來,嘗試新的東西,即使很基礎(chǔ)很簡單

小程序選型

小程序的第三方框架有很多, 我接觸過的就有 taro / wepy / mpvue ,并且都有對應(yīng)上線的項目。 在嘗試這些框架的過程中,對比原生小程序,有一些感想想分享出來:

  • 第三方框架語法貼近vue/react, 開發(fā)者可以根據(jù)自己的特點選擇框架,學(xué)習(xí)成本相對較低
  • 原生框架在CSS預(yù)處理,多端復(fù)用,狀態(tài)管理,自動構(gòu)建這幾塊能力對比其他框架是欠缺的
  • 第三方框架額外的工具包會使打包體積變大,每次構(gòu)建花費時間,同時性能不如原生
  • 第三方框架更新迭代很快,比如wepy@1.x/wepy@2, 導(dǎo)致舊項目的更新問題
  • 小程序的特性更新迭代速度較快, 第三方框架會相對滯后

綜上所述,由于我們目前沒有多端復(fù)用的要求,并且有的小程序相對簡單,需要很短時間內(nèi)開發(fā)完成, 最重要的是,其他的框架我都試過了,原生的還沒寫過,一個字,新鮮感!!:smile: ,所以最終當(dāng)仁不讓地選擇了原生小程序,不得不說,原生大法就是妙啊! :clap::clap::clap::clap:

大體思路

這個功能是相對很基礎(chǔ)的,但是作為一個每天搬磚的業(yè)務(wù)仔來說,是個艱難的過程,也是個很好的學(xué)習(xí)機會。

在做之前,想找找個社區(qū)比較:ox::beer:的學(xué)習(xí)(抄)一下,短暫考慮后,果斷選擇 taro-cli , 然后火速打開源碼,一頓操作(完全蒙圈),學(xué)習(xí)了一點之后,才開始上手

這個具體的實現(xiàn)思路我想到兩個

  • git clone 遠(yuǎn)程倉庫作為模版下載到本地,再根據(jù)用戶輸入配置修改 .json 文件(比如 appId )
  • template 就放在當(dāng)前目錄中,直接`copy``, 之后的事等同

權(quán)衡之后,打算使用 lerna 作為管理工具, 其中模版也作為一個 npm 包 ,用到的時候去 npm 下載,這么做我是為了方便管理,統(tǒng)一 push / publish , 就是為了省事 :smile:。

最終思路:

暴露命令 —> 用戶交互輸入配置 -> 集合配置下載模版 -> 根據(jù)配置修改 .json -> git init + 安裝依賴

開發(fā) Node CLI

Lerna 項目搭建

知道 monorepo 的同學(xué)不需要我多說,其實就是把代碼放在一個倉庫里,結(jié)果包之間回想以來,發(fā)布繁瑣等問題, 這里我們就用到了 lerna 這個神器幫助我們做包的統(tǒng)一管理

// 創(chuàng)建項目
mkdir modoo-mini-program
cd modoo-mini-program

// 初始化
lerna init

cd packages
mkdir modoo-script
mkdir modoo-template-mini
mkdir modoo-mini // 安裝 modoo-script 依賴用于測試,無其他實際用處

lerna bootstrap // 安裝依賴 + npm link

安裝依賴

為了實現(xiàn)功能,我們需要安裝一些依賴包

  • commander 命令行工具,用于讀取命令參數(shù),作對應(yīng)操作
  • node-fs-extra 在 Node.js 的 fs 基礎(chǔ)上增加了一些新的方法,更好用,還可以拷貝模板。
  • chalk 可以用于控制終端輸出字符串的樣式, 調(diào)整顏色啥的
  • inquirer 用戶命令行交互,獲取用戶的交互配置數(shù)據(jù),就像個提問板
  • ora 實現(xiàn)加載中的狀態(tài)是一個 Loading 加前面轉(zhuǎn)起來的小圈圈,成功了是一個 Success 加前面一個小鉤鉤。
  • log-symbols 日志彩色符號,用來顯示√ 或 × 等的圖標(biāo)

獲取命令

首先第一步,要在用戶全局安裝之后,暴露出命令接口,需要在 packages.json 文件中加入如下內(nèi)容

"bin": {
  "modoo-script": "./bin/modoo-script.js"
},

之后在根目錄下創(chuàng)建 bin 文件夾 + bin/modoo-script.js

#!/usr/bin/env node
const { program } = require("commander");

program
 .version(require("../package").version) // modoo-script --version
 .usage("<command> [options]")
 // init 命令,床架項目
 .command("init [projectName]", "Init a project with default templete")
 .parse(process.argv); // 解析命令參數(shù)

然后需要注意的是, commander 支持 Git 風(fēng)格的子命令處理,可以根據(jù)子命令自動引導(dǎo)到以特定格式命名的命令執(zhí)行文件,文件名的格式是 [command]-[subcommand] ,例如:

modoo-script init => modoo-script-init
modoo-script build => modoo-script-build

所以為了實現(xiàn) init 命令,可以直接在 bin 文件目錄下添加 modoo-script-init.js

#!/usr/bin/env node

const { program } = require("commander");

program
 .option("--name [name]", "項目名稱")
 .option("--description [description]", "項目介紹")
 .option("--framework", "腳手架框架")
 .parse(process.argv);

const args = program.args;
// 獲取命令參數(shù)
const { name, description, framework } = program;

const projectName = args[0] || name;

......

用戶交互

獲取了命令參數(shù)后,根據(jù)參數(shù)轉(zhuǎn)到用戶交互界面,這里使用的是 inquirer 來處理命令行交互, 用法很簡單

const inquirer = require('inquirer')

if (typeof conf.description !== 'string') {
   prompts.push({
    type: 'input',
    name: 'description',
    message: '請輸入項目介紹!'
   })
}

......

inquirer.prompt(prompts).then(answers => {
  // 整合配置
  this.conf = Object.assign(this.conf, answers);
})

遠(yuǎn)程模塊

這里較為折騰,一開始說了,我把模版作為 npm包 ,具體查找,下載的過程如下

  • npm search 查找相應(yīng)的模版 npm 包
  • 在用戶選擇框架后對應(yīng)所需的包,獲取它的詳細(xì)信息,主要是 tarball
  • 用戶輸入完后,下載 tarball 到項目目錄,并修改 .json 文件配置

部分代碼如圖所示

// 一 npm search 查找相應(yīng)的模版 npm 包
const { execSync } = require("child_process");

module.exports = () => {
 let list = [];
 try {
  const listJSON = execSync(
   "npm search --json --registry http://registry.npmjs.org/ @modoo/modoo-template"
  );
  list = JSON.parse(listJSON);
 } catch (error) {}

 return Promise.resolve(list);
};
// 二 返回 npm 數(shù)據(jù)
const pkg = require("package-json");
const chalk = require("chalk");
const logSymbols = require("log-symbols");

exports.getBoilerplateMeta = framework => {
 log(
  logSymbols.info,
  chalk.cyan(`您已選擇 ${framework} 遠(yuǎn)程模版, 正在查詢該模版...`)
 );

 return pkg(framework, {
  fullMetadata: true
 }).then(metadata => {
  const {
   dist: { tarball },
   version,
   name,
   keywords
  } = metadata;
  log(
   logSymbols.success,
   chalk.green(`已為您找到 ${framework} 遠(yuǎn)程模版, 請輸入配置信息`)
  );

  return {
   tarball,
   version,
   keywords,
   name
  };
 });
};
// 三 下載 npm 包
const got = require("got");
const tar = require("tar");
const ora = require("ora");

const spinner = ora(
  chalk.cyan(`正在下載 ${framework} 遠(yuǎn)程模板倉庫...`)
).start();

const stream = await got.stream(tarball);

fs.mkdirSync(proPath);

const tarOpts = {
 strip: 1,
 C: proPath
};

// 管道流傳輸下載文件到當(dāng)前目錄
stream.pipe(tar.x(tarOpts)).on("close", () => {
  spinner.succeed(chalk.green("下載遠(yuǎn)程模塊完成!"));
  ......
})
// 四 遍歷文件修改配置
const fs = require("fs-extra");

readFiles(
  proPath,
  {
   ignore: [
    ".{pandora,git,idea,vscode,DS_Store}/**/*",
    "{scripts,dist,node_modules}/**/*",
    "**/*.{png,jpg,jpeg,gif,bmp,webp}"
   ],
   gitignore: true
  },
  ({ path, content }) => {
   fs.createWriteStream(path).end(template(content, inject));
  }
 );
 
// 遞歸讀文件
exports.readFiles = (dir, options, done) => {
 if (!fs.existsSync(dir)) {
  throw new Error(`The file ${dir} does not exist.`);
 }
 if (typeof options === "function") {
  done = options;
  options = {};
 }
 options = Object.assign(
  {},
  {
   cwd: dir,
   dot: true,
   absolute: true,
   onlyFiles: true
  },
  options
 );

 const files = globby.sync("**/**", options);
 files.forEach(file => {
  done({
   path: file,
   content: fs.readFileSync(file, { encoding: "utf8" })
  });
 });
};

// 配置替換
exports.template = (content = "", inject) => {
 return content.replace(/@{([^}]+)}/gi, (m, key) => {
  return inject[key.trim()];
 });
};

下載依賴

下載完畢并且修改完配置后, 默認(rèn)執(zhí)行 git init + 根據(jù)環(huán)境( yarn / npm / cnpm )安裝依賴,這個就很簡單了

const { exec } = require("child_process");
const ora = require("ora");
const chalk = require("chalk");

// proPath 項目目錄
process.chdir(proPath);

// git init
const gitInitSpinner = ora(
 `cd ${chalk.cyan.bold(projectName)}, 執(zhí)行 ${chalk.cyan.bold("git init")}`
).start();

const gitInit = exec("git init");
gitInit.on("close", code => {
 if (code === 0) {
  gitInitSpinner.color = "green";
  gitInitSpinner.succeed(gitInit.stdout.read());
 } else {
  gitInitSpinner.color = "red";
  gitInitSpinner.fail(gitInit.stderr.read());
 }
});

// install
let command = "";
if (shouldUseYarn()) {
 command = "yarn";
} else if (shouldUseCnpm()) {
 command = "cnpm install";
} else {
 command = "npm install";
}

log(" ".padEnd(2, "\n"));
const installSpinner = ora(
 `執(zhí)行安裝項目依賴 ${chalk.cyan.bold(command)}, 需要一會兒...`
).start();

exec(command, (error, stdout, stderr) => {
  if (error) {
   installSpinner.color = "red";
   installSpinner.fail(chalk.red("安裝項目依賴失敗,請自行重新安裝!"));
   console.log(error);
  } else {
   installSpinner.color = "green";
   installSpinner.succeed("安裝成功");
   log(`${stderr}${stdout}`);
  }
});

主要的代碼就是這些,其實只要知道思路,這些東西都很簡單,雖然我寫的有點 ️:chicken:,但是主要的邏輯還是能理清楚的一些的。更加詳細(xì)的可以去:eyes:我發(fā)的源碼,多謝指教。:pray::pray::pray:

開發(fā)腳手架

因為這是小程序的腳手架,它不像其他 web 框架一樣需要很多 webpack 的配置,所以相對簡單很多。

對于這個腳手架,相比于開發(fā)者工具創(chuàng)建的默認(rèn)項目,我彌補了它的一些問題

  1. 默認(rèn)項目太過簡單,只適合自己折騰,對于團(tuán)隊或者企業(yè),缺乏相應(yīng)的代碼約定/規(guī)范,沒有強制的約定會導(dǎo)致團(tuán)隊協(xié)作間的困難,提升code review的難度,所以我在原來的基礎(chǔ)上加入了eslint,stylelint,prettier,commitlint等配置,以及git hook 在 pre-commit 時,執(zhí)行校驗,確保提交的代碼盡量規(guī)范
  2. 由于對 css 預(yù)處理的鐘愛,另外加入了對 less 的支持,并且解決小程序背景圖不支持本地圖片的問題
  3. 由于以上基本都是文件處理,所以選擇 gulp 作為構(gòu)建工具,這里是 v4, 與v3 寫法上有一定的區(qū)別,不過關(guān)系不大

在根目錄下創(chuàng)建 gulpfile.js

const gulp = require('gulp');
const chalk = require('chalk');
const rename = require('gulp-rename');

// 支持 less
gulp.task('less', () => {
 return gulp
  .src('./miniprogram/**/*.less')
  .pipe(less())
  .pipe(postcss()) // 配置在 post.config.js
  .pipe(
   rename((path) => {
    path.extname = '.wxss';
   })
  )
  .pipe(
   gulp.dest((file) => {
    return file.base; // 原目錄
   })
  );
});

// 開發(fā)環(huán)境監(jiān)聽 less
if (env === 'development') {
 gulp.watch(['./miniprogram/**/*.less'], gulp.series('less')).on('change', (path) => {
  log(chalk.greenBright(`File ${path} was changed`));
 });
}


// 一下代碼注釋掉了,依賴包下載太慢了,這主要負(fù)責(zé)圖片的壓縮
const imagemin = require('gulp-imagemin');
const cache = require('gulp-cache'); // 使用緩存

gulp.task('miniimage', () => {
 return gulp
  .src('./miniprogram/**/*.{png,jpe?g,gif,svg}')
  .pipe(
   cache(
    imagemin([
     imagemin.gifsicle({ interlaced: true }),
     imagemin.mozjpeg({ quality: 75, progressive: true }),
     imagemin.optipng({ optimizationLevel: 5 }),
     imagemin.svgo({
      plugins: [{ removeViewBox: true }, { cleanupIDs: false }],
     }),
    ])
   )
  )
  .pipe(
   gulp.dest((file) => {
    return file.base; // 原目錄
   })
  );
});

其他的一些具體配置,可以看我的GitHub 倉庫源碼

參考

taro-cli

pandora-cli

little-bird-cli

到此這篇關(guān)于開發(fā)Node CLI構(gòu)建微信小程序腳手架的示例的文章就介紹到這了,更多相關(guān)Node CLI構(gòu)建小程序腳手架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問)

    基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問)

    Node-Red是IBM公司開發(fā)的一個可視化的編程工具,在網(wǎng)頁內(nèi)編程,主要是拖拽控件,代碼量很小,這篇文章主要介紹了基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問),需要的朋友可以參考下
    2022-01-01
  • Node.js常用三大模塊之path模塊

    Node.js常用三大模塊之path模塊

    在node.js中常用的三大模塊中還有一個是path模塊,主要是為了便利用戶處理路徑問題,如果我們在引入文件的時候經(jīng)常會受到../和./的干擾,那么這個path模塊將會很好的幫助你
    2022-09-09
  • 開發(fā)Node CLI構(gòu)建微信小程序腳手架的示例

    開發(fā)Node CLI構(gòu)建微信小程序腳手架的示例

    這篇文章主要介紹了開發(fā)Node CLI構(gòu)建微信小程序腳手架,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Node.js下自定義錯誤類型詳解

    Node.js下自定義錯誤類型詳解

    在JavaScript里面,運行過程中的錯誤的類型總是被人忽略,這篇文章給大家詳細(xì)介紹了如何在Node.js下自定義錯誤類型,對大家學(xué)習(xí)或者使用Node.js具有一定的參考借鑒價值,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-10-10
  • Node.js的特點詳解

    Node.js的特點詳解

    本文主要對Node.js的特點進(jìn)行詳細(xì)介紹。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 推薦 21 款優(yōu)秀的高性能 Node.js 開發(fā)框架

    推薦 21 款優(yōu)秀的高性能 Node.js 開發(fā)框架

    Node.js是JavaScript中最為流行的框架之一,易于創(chuàng)建可擴展的Web應(yīng)用。Node.js包含不同類型框架,包括MVC, full-stack,REST API以及Generators。借助這些框架使Node.js更加易于使用,它還支持眾多特性功能,只需幾個步驟就可快速搭建強大的Web應(yīng)用。本文為大家推薦21款
    2014-08-08
  • 推薦一個基于Node.js的表單驗證庫

    推薦一個基于Node.js的表單驗證庫

    這篇文章主要介紹了推薦一個基于Node.js的表單驗證庫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • 手寫簡版無三方依賴的Node-Server實現(xiàn)示例

    手寫簡版無三方依賴的Node-Server實現(xiàn)示例

    這篇文章主要為大家介紹了手寫簡版無三方依賴的Node-Server實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • node中的密碼安全(加密)

    node中的密碼安全(加密)

    這篇文章主要介紹了node中的密碼安全(加密),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • npm?install安裝失敗常見問題的解決辦法小結(jié)

    npm?install安裝失敗常見問題的解決辦法小結(jié)

    有時候前端安裝npm install 安裝包總是安裝不上,下面這篇文章主要給大家介紹了關(guān)于npm?install安裝失敗常見問題的解決辦法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05

最新評論

邵阳县| 通山县| 常州市| 东光县| 祁门县| 林周县| 日喀则市| 视频| 海淀区| 治多县| 泉州市| 铁岭县| 清涧县| 靖安县| 鄱阳县| 永仁县| 浦东新区| 吉安县| 三门县| 通化县| 青海省| 射阳县| 兴宁市| 曲沃县| 定结县| 丰镇市| 乐平市| 金沙县| 贵南县| 连云港市| 濮阳市| 平昌县| 天津市| 安义县| 蕲春县| 息烽县| 惠水县| 甘谷县| 南皮县| 杭锦后旗| 交城县|