日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
從0到1構(gòu)建基于自身業(yè)務(wù)的前端工具庫

作者:京東零售

目前成都創(chuàng)新互聯(lián)公司已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、衡南網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

前言

?在實(shí)際項(xiàng)目開發(fā)中無論 M 端、PC 端,或多或少都有一個(gè) utils 文件目錄去管理項(xiàng)目中用到的一些常用的工具方法,比如:時(shí)間處理、價(jià)格處理、解析url參數(shù)、加載腳本等,其中很多是重復(fù)、基礎(chǔ)、或基于某種業(yè)務(wù)場景的工具,存在項(xiàng)目間冗余的痛點(diǎn)以及工具方法規(guī)范不統(tǒng)一的問題。

?在實(shí)際開發(fā)過程中,經(jīng)常使用一些開源工具庫,如 lodash,以方便、快捷的進(jìn)行項(xiàng)目開發(fā)。但是當(dāng) npm上沒有自己中意或符合自身業(yè)務(wù)的工具時(shí),我們不得不自己動手,此時(shí)擁有自己的、基于業(yè)務(wù)的工具庫就顯得尤為重要。

?我們所熟知的Vue、React等諸多知名前端框架,或公司提供的一些類庫,它們是如何開發(fā)、構(gòu)建、打包出來的,本文將帶領(lǐng)你了解到如何從0到1構(gòu)建基于自身業(yè)務(wù)的前端工具庫。

構(gòu)建工具庫主流方案

1. WEBPACK

? webpack 提供了構(gòu)建和打包不同模塊化規(guī)則的庫,只是需要自己去搭建開發(fā)底層架構(gòu)。

? vue-cli,基于 webpack , vue-cli 腳手架工具可以快速初始化一個(gè) vue 應(yīng)用,它也可以初始化一個(gè)構(gòu)建庫。

2. ROLLUP

? rollup 是一個(gè)專門針對JavaScript模塊打包器,可以將應(yīng)用或庫的小塊代碼編譯成更復(fù)雜的功能代碼。

? Vue、React 等許多流行前端框架的構(gòu)建和打包都能看到 rollup 的身影。

為什么采用 ROLLUP 而不是 WEBPACK

?webpack 主要職能是開發(fā)應(yīng)用,而 rollup 主要針對的就是 js 庫的開發(fā),如果你要開發(fā) js 庫,那 webpack 的繁瑣配置和打包后的文件體積就不太適用了,通過webpack打包構(gòu)建出來的源代碼增加了很多工具函數(shù)以外的模塊依賴代碼。

?rollup 只是把業(yè)務(wù)代碼轉(zhuǎn)碼成目標(biāo) js ,小巧且輕便。rollup對于代碼的Tree-shaking和ES6模塊有著算法優(yōu)勢上的支持,如果只想構(gòu)建一個(gè)簡單的庫,并且是基于ES6開發(fā)的,加上其簡潔的API,rollup得到更多開發(fā)者的青睞。

工具庫底層架構(gòu)設(shè)計(jì)

構(gòu)建工具庫底層架構(gòu)大概需要哪些功能的支持:

架構(gòu)依賴需知

在對底層架構(gòu)設(shè)計(jì)的基礎(chǔ)上,首先需要把用到的依賴庫簡單熟悉一下:

rollup 全家桶

?? rollup(工具庫打包構(gòu)建核心包)

?? rollup-plugin-livereload(rollup 插件,熱更新,方便本地 debugger 開發(fā))

?? rollup-plugin-serve(rollup 插件,本地服務(wù)代理,方便在本地 html 中調(diào)試工具)

?? rollup-plugin-terser(rollup 插件,代碼壓縮混淆)

?? rollup-plugin-visualizer(rollup 插件,可視化并分析 Rollup bundle,以查看模塊占用)

?? @rollup/plugin-babel(rollup 插件,rollup 的 babel 插件,ES6 轉(zhuǎn) ES5)

?? @rollup/plugin-commonjs(rollup 插件,用來將 CommonJS 模塊轉(zhuǎn)換為 ES6,這樣它們就可以包含在 Rollup 包中)

?? @rollup/plugin-json(rollup 插件,它將.json 文件轉(zhuǎn)換為 ES6 模塊)

?? @
rollup/plugin-node-resolve(rollup 插件,它使用節(jié)點(diǎn)解析算法定位模塊,用于在節(jié)點(diǎn)模塊中使用第三方 node_modules 包)

?? @rollup/plugin-typescript(rollup 插件,對 typescript 的支持,將 typescript 進(jìn)行 tsc 轉(zhuǎn)為 js)

typescript 相關(guān)

?? typescript(使用 ts 開發(fā)工具庫)

?? tslib(TypeScript 的運(yùn)行庫,它包含了 TypeScript 所有的幫助函數(shù))

?? @
typescript-eslint/eslint-plugin(TypeScript 的 eslint 插件,約束 ts 書寫規(guī)范)

?? @typescript-eslint/parser(ESLint 解析器,它利用 TypeScript ESTree 來允許 ESLint 檢測 TypeScript 源代碼)

文檔相關(guān)

?? typedoc(TypeScript 項(xiàng)目的文檔生成器)

?? gulp(使用 gulp 構(gòu)建文檔系統(tǒng))

?? gulp-typedoc(Gulp 插件來執(zhí)行 TypeDoc 工具)

?? browser-sync(文檔系統(tǒng)熱更新)

單元測試相關(guān)

?? jest(一款優(yōu)雅、簡潔的 JavaScript 測試框架)

?? @types/jest(Jest 的類型定義)

?? ts-jest(一個(gè)支持源映射的 Jest 轉(zhuǎn)換器,允許您使用 Jest 來測試用 TypeScript 編寫的項(xiàng)目)

?? @babel/preset-typescript(TypeScript 的 Babel 預(yù)設(shè))

其他依賴

?? eslint(代碼規(guī)范約束)

?? @babel/core(@rollup/plugin-babel 依賴的 babel 解析插件)

?? @
babel/plugin-transform-runtime(babel 轉(zhuǎn)譯依賴)

?? @babel/preset-env(babel 轉(zhuǎn)譯依賴)

?? chalk(控制臺字符樣式)

?? rimraf(UNIX 命令 rm -rf 用于 node)

?? cross-env(跨平臺設(shè)置 node 環(huán)境變量)

底層架構(gòu)搭建

1. 初始化項(xiàng)目

新建一個(gè)文件夾 utils-demo,執(zhí)行 npm init,過程會詢問構(gòu)建項(xiàng)目的基本信息,按需填寫即可:

npm init

2. 組織工具庫業(yè)務(wù)開發(fā) SRC 目錄結(jié)構(gòu)

創(chuàng)建工具庫業(yè)務(wù)開發(fā) src 文件目錄,明確怎樣規(guī)劃工具庫包,里面放置的是工具庫開發(fā)需要的業(yè)務(wù)代碼:

3. 安裝項(xiàng)目依賴

要對 typescript 代碼進(jìn)行解析支持需要安裝對 ts 支持的依賴,以及對開發(fā)的工具的一些依賴包:

yarn add typescript tslib rollup rollup-plugin-livereload rollup-plugin-serve rollup-plugin-terser rollup-plugin-visualizer 
@rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @rollup/plugin-typescript 
@babel/core @babel/plugin-transform-runtime @babel/preset-env rimraf lodash chalk@^4.1.2 -D

這里遇到一個(gè)坑,關(guān)于最新 chalk5.0.0 不支持在 nodejs 中 require()導(dǎo)入,所以鎖定包版本 chalk@^4.1.2

要對 typescript 進(jìn)行解析和編譯還需要配置 tsconfig.json,該文件中指定了用來編譯這個(gè)項(xiàng)目的根文件和編譯選項(xiàng),在項(xiàng)目根目錄,使用 tsc --init 命令快速生成 tsconfig.json 文件(前提全局安裝 typescript)

npm i typescript -g
tsc --init

初始化 tsconfig 完成之后,根目錄自動生成 tsconfig.json 文件,需要對其進(jìn)行簡單的配置,以適用于 ts 項(xiàng)目,其中具體含義可以參考tsconfig.json官網(wǎng)

4. 組織項(xiàng)目打包構(gòu)建 SCRIPTS 目錄結(jié)構(gòu)

1) 根目錄創(chuàng)建項(xiàng)目打包構(gòu)建 scripts 腳本文件目錄,里面放置的是有關(guān)于項(xiàng)目打包構(gòu)建需要的文件:

生成rollup配置項(xiàng)函數(shù)核心代碼:

const moduleName = camelCase(name) // 當(dāng)format為iife和umd時(shí)必須提供,將作為全局變量掛在window下:window.moduleName=...
const banner = generateBanner() // 包說明文案
// 生成rollup配置文件函數(shù)
const generateConfigs = (options) => {
  const { input, outputFile } = options
  console.log(chalk.greenBright(`獲取打包入口:${input}`))
  const result = []
  const pushPlugins = ({ format, plugins, ext }) => {
    result.push({
      input, // 打包入口文件
      external: [], // 如果打包出來的文件有項(xiàng)目依賴,可以在這里配置是否將項(xiàng)目依賴一起打到包里面還是作為外部依賴
      // 打包出口文件
      output: {
        file: `${outputFile}${ext}`, // 出口文件名稱
        sourcemap: true, // // 是否生成sourcemap
        format, // 打包的模塊化格式
        name: moduleName, // 當(dāng)format為iife和umd時(shí)必須提供,將作為全局變量掛在window下:window.moduleName=...
        exports: 'named' /** Disable warning for default imports */,
        banner, // 打包出來的文件在最頂部的說明文案
        globals: {} // 如果external設(shè)置了打包忽略的項(xiàng)目依賴,在此配置,項(xiàng)目依賴的全局變量
      },
      plugins // rollup插件
    })
  }
  buildType.forEach(({ format, ext }) => {
    let plugins = [...defaultPlugins]
    // 生產(chǎn)環(huán)境加入包分析以及代碼壓縮
    plugins = [
      ...plugins,
      visualizer({
        gzipSize: true,
        brotliSize: true
      }),
      terser()
    ]

    pushPlugins({ format, plugins, ext })
  })
return result
}

2) rollup 在打包構(gòu)建的過程中需要進(jìn)行 babel 的轉(zhuǎn)譯,需要在根目錄添加.babelrc 文件告知 babel:

{
  "presets": [
    [
      "@babel/preset-env"
    ]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}

3) 此時(shí)距離打包構(gòu)建工具庫只差一步之遙,配置打包腳本命令,在 package.json 中配置命令:

"scripts": {
    "build": "rimraf lib && rollup -c ./scripts/rollup.config.js" // rollup打包
 },

4) 執(zhí)行 yarn build,根目錄會構(gòu)建出一個(gè) lib 文件夾,里面有打包構(gòu)建的文件,還多了一個(gè) stats.html,這個(gè)是可視化并分析 Rollup bundle,用來查看工具模塊占用空間:

架構(gòu)搭建優(yōu)化

項(xiàng)目搭建到這里,不知機(jī)智的你能否發(fā)現(xiàn)問題:

1) 只要添加了一個(gè)工具,就要在入口文件導(dǎo)出需要打包構(gòu)建的工具,在多人開發(fā)提交代碼的時(shí)候?qū)⒁齺頉_突的產(chǎn)生:

2) 使用工具庫的時(shí)候,按需引用的顆粒度太細(xì)了,不能滿足一些要求顆粒度粗的朋友,比如:

?? 我想使用該包里面 date 相關(guān)工具,要這樣嗎?

import { dateA, dateB, dateC } from "utils-demo"

能不能這樣?

import { date } from "utils-demo"
date.dateA()
date.dateB()
date.dateC()

?? 在一些使用 script 腳本引入的場景下,就僅僅需要 date 相關(guān)的工具,要這樣嗎?