
前端構建工具【免費下載鏈接】css-blocksHigh performance, maintainable stylesheets.項目地址https://gitcode.com/gh_mirrors/cs/css-blocks點擊查看免費下載css-blocks/ember-app是 CSS Blocks 在 Ember 生態(tài)中的核心 ember-cli addon負責將應用內(nèi)所有 CSS Blocks 內(nèi)容聚合、經(jīng) OptiCSS 優(yōu)化后拼接進最終樣式產(chǎn)物并生成模板運行時所需的類名數(shù)據(jù)與測試支持數(shù)據(jù)。本文以該包的 CHANGELOG 為脈絡結合 README 與倉庫源碼完整講解它的集成方式、ember-cli-build.js配置項、構建管線底層實現(xiàn)以及 1.2.0 → 1.5.0 的關鍵能力演進讀完即可在 Ember 應用中正確接入并排查 CSS Blocks 相關問題。一、這個 addon 在構建管線中的定位css-blocks/ember-app是一個面向 Ember 應用的 ember-cli addon應當作為應用的 dependency 安裝。它的職責在 src/index.ts 的注釋中有明確交代把應用以及依賴的 addon、engine里所有的 CSS Blocks 內(nèi)容打包在一起使用 OptiCSS 對編譯后的 CSS 進行優(yōu)化并拼接成最終產(chǎn)物生成一份 JSON 形式的運行時數(shù)據(jù)runtime data供模板重寫后解析該給組件加哪些類名提供一個運行時 helper 真正把類名寫出來額外生成測試支持數(shù)據(jù)test support data。關鍵前提css-blocks/ember-app假定所有中間 block 已經(jīng)由css-blocks/ember這個 addon 編譯成compiledblock.css與block-analysis.json。換句話說應用和它依賴的 addon/engine 只要有 CSS Blocks 文件就必須同時依賴css-blocks/ember否則本 addon 不會產(chǎn)出任何 CSS 輸出。另一個容易忽略的細節(jié)同樣記錄在 src/index.ts 的注釋中CSS Blocks 的編譯發(fā)生在模板樹Template tree而非樣式樹中。因為 CSS Blocks 需要同時推理模板與樣式才能完成模板重寫css-blocks/ember-app則負責在 CSS 樹階段把這些編譯結果合并進最終樣式。這就是為什么它會同時干預preprocessTree與postprocessTree兩個階段。二、基本使用三步接入按照 README 的說明接入只需要三步把css-blocks/ember-app添加為應用的依賴如果應用要使用 CSS Blocks 編寫樣式同時把css-blocks/ember添加為依賴執(zhí)行ember build。輸出行為分兩種場景如果應用存在app/styles/app.cssCSS Blocks 的構建輸出會被自動追加到該文件的末尾如果應用使用其他樣式文件名例如經(jīng)過了預處理器處理構建時會生成一個app/styles/css-blocks.css文件你可以把它 include/import 進預處理器或與其他文件拼接成應用的最終 CSS。如果應用使用了 engine則每個使用css-blocks/ember的 engine 都要把css-blocksservice 加入依賴。關于開發(fā)構建與生產(chǎn)構建的差異README 也給出了明確說明開發(fā)構建輸出帶開發(fā)者友好 BEM 類名的 CSS方便理解生產(chǎn)構建輸出經(jīng)過拼接、優(yōu)化和壓縮的 CSS 產(chǎn)物。三、ember-cli-build.js配置選項全解所有選項通過應用ember-cli-build.js中的css-blocks屬性傳入最終由 ember-utils/src/options.ts 定義的CSSBlocksEmberOptions接口解析。下面逐一展開。3.1output類型string默認值css-blocks.css見 options.ts作用改變 CSS Blocks 樣式寫入app/styles目錄的文件名。注意一旦設置該值樣式永遠不會自動與app/styles/app.css拼接。從源碼看該文件名在預處理階段位于app/styles/${output}后處理階段位于assets/${output}見 utils/filepaths.ts。若傳入的值不是字符串getConfig會直接拋出錯誤見 options.ts。3.2aliases類型object作用為 CSS Blocks 文件提供導入別名鍵對應別名值是指向包含 CSS Blocks 文件的目錄的絕對路徑。示例來自 README{myblocks: path.resolve(__dirname, ../blocks)}會讓block foo from myblocks/header.block.css;導入../blocks目錄下的header.block.css。實現(xiàn)默認 importer 是NodeJsImporter(options.aliases)見 options.ts。3.3analysisOpts類型模板分析選項。默認{}。作用傳給EmberAnalyzer的模板分析參數(shù)。README 明確提示你大概不需要設置這些屬于高級自定義項。3.4parserOpts類型傳給 CSS Blocks parser 和 compiler 的選項。默認行為如果沒有設置這些選項會自動從css-blocks.config.js配置文件加載config.searchSync(root)見 options.ts。使用配置文件的好處是css-blocks/cli等工具能與 Ember 應用加載到同一套選項。強制行為parserOpts.outputMode會被強制設為OutputMode.BEM_UNIQUE見 options.tsrootDir若未設置會被補上應用根目錄見 options.ts。3.5optimization類型傳給 OptiCSS optimizer 的選項。默認{}其中enabled未顯式設置時默認僅在生產(chǎn)構建isProduction時開啟見 options.ts。作用可選擇性開啟/關閉某些具體優(yōu)化或通過把enable設為false顯式關閉全部優(yōu)化。3.6broccoliConcat類型BroccoliConcatOptions | false完整接口見 ember-utils/src/options.ts。作用控制broccoli-concat在后處理階段拼接 CSS 的行為包括inputFiles、outputFile、header、headerFiles、footerFiles、footer、sourceMapConfig、allowNone等。特殊值設為false時broccoli-concat 不會運行你需要自行追加額外處理把 CSS Blocks 編譯內(nèi)容加入最終 CSS 產(chǎn)物。默認拼接行為把assets/css-blocks.css與assets/modulePrefix.css拼接輸出到assets/modulePrefix.css并開啟 css sourcemapmapCommentType: block、extensions: [css]詳見 src/index.ts。用戶提供的sourceMapConfig會被強制修正extensions與mapCommentType兩個字段見 src/index.ts避免拼接出錯。3.7appClasses類型string[]默認[]作用列出應用 CSS 中使用、可能與優(yōu)化器沖突的類名。README 建議把所有短類名約 5 個字符加入此列表防止優(yōu)化器在生成 CSS Blocks 編譯輸出時復用這些類名。實現(xiàn)這是optimization.rewriteIdents.omitIdents.class[]的便捷別名。在 src/broccoli-plugin.ts 的reserveClassnames()中appClasses會被 push 進omitIdents.class列表同時rewriteIdents.id被強制設為false不重寫 idclass保留用戶設置。若優(yōu)化被禁用該選項不生效。四、構建管線源碼級拆解css-blocks/ember-app的構建邏輯集中在兩個文件addon 主入口 src/index.ts 與三個 broccoli 插件 src/broccoli-plugin.ts。4.1 JS 樹預處理收集模板分析產(chǎn)物在preprocessTree(js)階段見 src/index.ts只有isApp為真的環(huán)境會執(zhí)行核心邏輯遍歷所有啟用了 lazy loading 的 lazy engine addon找到其中依賴css-blocks/ember的 addon取其templateCompiler的模板輸出合并進一個lazy-tree-output子目錄用CSSBlocksApplicationPlugin處理[app.addonTree(), tree, lazyOutput]三棵樹的合并結果產(chǎn)出優(yōu)化后的模板樹css-blocks:optimized。也就是說lazy engine 的模板分析與 CSS 輸出會被并入應用構建這正是 CHANGELOG 中多處提到支持 lazy engines的底層機制。從 1.2.0 的egregious hack到 1.2.1 的slightly less hacky approach再到preprocessTree中基于a.lazyLoading a.lazyLoading.enabled true的顯式過濾邏輯lazy engine 支持是逐步收斂成形的。4.2 CSS 樹預處理把編譯產(chǎn)物搬進樣式樹preprocessTree(css)階段見 src/index.ts使用CSSBlocksStylesPreprocessorPlugin實現(xiàn)見 broccoli-plugin.ts把 JS 樹階段生成的 CSS Blocks 編譯內(nèi)容復制到 CSS 樹中默認位置app/styles/css-blocks.css并轉(zhuǎn)發(fā)優(yōu)化器生成的類名列表 JSONapp/styles/css-blocks-stylelist.json。如果插件實例尚未創(chuàng)建JS 樹未跑會拋出明確的錯誤提示——這在正常情況下不會發(fā)生因為 JS 樹總是先于 CSS 樹處理。4.3CSSBlocksApplicationPlugin核心編譯與優(yōu)化這是整個 addon 的心臟見 broccoli-plugin.ts。它的build()流程可以概括為掃描輸入樹中的**/*.{compiledblock.css,block-analysis.json}用fs-tree-diff計算增量 patch沒有變化就跳過重編譯首次構建會生成一份空的運行時數(shù)據(jù)文件避免運行時錯誤見 broccoli-plugin.ts解析配置、構造BlockFactory與EmberAnalyzer對每個block-analysis.json反序列化分析結果收集所有傳遞依賴的 block加入 OptiCSS optimizer對每個 block優(yōu)先復用未編輯的預編譯 CSSblock.precompiledStylesheetUnedited否則用BlockCompiler重新編譯然后作為 source 加入 optimizer調(diào)用optimizer.optimize(cssFileName)得到優(yōu)化后的 CSS并把 sourcemap 以 base64 內(nèi)聯(lián)注釋的形式追加到 CSS 末尾addSourcemapInfoToOptimizedCss見 broccoli-plugin.ts——這就是 CHANGELOG 1.4.0 End-to-end sourcemaps for ember v2 pipeline 的實現(xiàn)落點寫出優(yōu)化 CSS、優(yōu)化日志cssFileName.optimization.log以及優(yōu)化器生成的類名清單app/styles/css-blocks-stylelist.json后者用于后處理階段的沖突檢測用RuntimeDataGenerator生成運行時數(shù)據(jù)appName/services/-css-blocks-data.js非生產(chǎn)構建額外生成測試支持數(shù)據(jù)appName/services/-css-blocks-test-support-data.js見 broccoli-plugin.ts。運行時數(shù)據(jù)的結構由 AggregateRewriteData.ts 定義包含blockIds、blocks、outputClassnames、styleRequirements、impliedStyles、optimizations等字段空的初始數(shù)據(jù)結構可見 broccoli-plugin.ts。生成邏輯在 RuntimeDataGenerator.ts 中為每個 block、style 分配全局索引把優(yōu)化后的類名映射到outputClassnames數(shù)組下標把樣式需求styleRequirements與隱含樣式impliedStyles編碼成可供運行時求值的表達式——CHANGELOG 1.3.0 中Emit attribute groups in the runtime aggregate rewrite data與Simplify rewrite for dynamic attribute values兩項 feature 正是在這里落地屬性組attribute groups被寫入聚合運行時數(shù)據(jù)動態(tài)屬性值的重寫被簡化為基于 styleId 的索引求值。4.4 CSS 后處理沖突檢測與拼接postprocessTree(css)階段見 src/index.ts做兩件事類名沖突檢測僅優(yōu)化開啟時CSSBlocksStylesPostprocessorPlugin見 broccoli-plugin.ts讀取后處理樹中的assets/css-blocks-stylelist.json優(yōu)化器生成的類名再用 postcss 解析應用 CSS 中所有.class選擇器找出同時出現(xiàn)在應用 CSS 與優(yōu)化器輸出中的類名。若存在沖突構建直接拋錯錯誤信息會列出沖突類名及文件與行列位置——這正是 CHANGELOG 1.5.0 Add fileloc to class name conflict error 與 Class name collision detection 兩項功能的實現(xiàn)同時會生成assets/app-classes.log供排查。錯誤信息明確建議把非 block CSS 中的短類名約 5 個字符加入css-blocks.appClasses。broccoli-concat 拼接把assets/css-blocks.css與assets/modulePrefix.css拼成最終產(chǎn)物然后從樹中剔除中間文件css-blocks.css與優(yōu)化類名列表 JSON見 src/index.ts——對應 CHANGELOG 1.5.0 的 Prune css-blocks.css from the output after concatenating it。4.5 端到端 sourcemapCHANGELOG 1.4.0 的 End-to-end sourcemaps for ember v2 pipeline 意味著 sourcemap 貫穿三個階段優(yōu)化器輸出內(nèi)聯(lián) sourcemapaddSourcemapInfoToOptimizedCss、broccoli-concat 強制開啟sourceMapConfig.enabled且修正extensions: [css]、mapCommentType: block見 src/index.ts。這樣最終拼接產(chǎn)物能一路映射回原始 block 文件。五、運行時服務類名如何落到元素上運行時數(shù)據(jù)由應用命名空間下的css-blocksservice 消費實現(xiàn)在 runtime/app/services/css-blocks.ts 中。CSSBlocksService.classNamesFor()是核心入口它的求值分三步直接應用樣式用StyleEvaluator根據(jù)模板重寫時傳入的參數(shù)styleId、狀態(tài)、屬性值等計算出直接應用的 styleId 集合隱含樣式解析用StyleResolver根據(jù)styleRequirements補全必須同時應用的樣式并產(chǎn)出隱含類名——這是 CSS Blocks 樣式需求style requirements與隱含樣式implied styles的運行時實現(xiàn)優(yōu)化樣式應用遍歷optimizations數(shù)組用 AND/OR/NOT 布爾表達式evaluateExpression見 css-blocks.ts判斷當前 style 集合是否命中某項優(yōu)化命中則追加outputClassnames[idx]。調(diào)試支持service 上有enableDebugMode開啟后會在控制臺打印參數(shù)、直接/隱含樣式名與最終類名debugExpression能把優(yōu)化條件表達式還原成可讀的 style 名。這些能力與 CHANGELOG 1.2.0 的 Basic runtime style calculations working、Implied style runtime support、Enable optimizer and runtime rewriting of optimized styles 等 feature 一一對應。1.3.0 的 Extract StyleEvaluator, StyleResolver classes from runtime service 則是把求值邏輯從 service 中拆分成了獨立的類。六、測試支持setupCSSBlocksTest()優(yōu)化后的類名在不同構建、不同機器上都會變化這是有意為之防止測試里硬編碼類名因此 addon 提供了測試工具方法setupCSSBlocksTest()與ember-qunit和ember-mocha兼容。6.1 使用規(guī)則在集成測試或驗收測試中、聲明任何 test 之前調(diào)用setupCSSBlocksTest()且必須在setupTest | setupRenderingTest | setupApplicationTest之后調(diào)用。源碼中若檢測不到this.owner會直接拋錯setupCSSBlocksTest must be called after setupTest|setupRenderingTest|setupApplicationTest見 css-blocks-test-support.ts。該函數(shù)暴露在應用命名空間的 service 上需要這樣導入import { setupCSSBlocksTest } from appName/services/css-blocks-test-support;調(diào)用后測試中可通過this.cssBlocks訪問 css-blocks service。6.2 核心 API測試 service 主要暴露一個方法this.cssBlocks.getBlock(pathToBlock, blockName)。pathToBlock必須以應用名、in-repo addon 名或 in-repo engine 名開頭表示它所屬的命名空間blockName可選缺省時返回該 block 文件的默認 block返回一個運行時 block 引用可通過.style(styleName)查詢塊內(nèi)樣式最終用原生element.classList.contains()斷言元素上是否存在該樣式。getBlock與TestBlock.style的實現(xiàn)細節(jié)見 css-blocks-test-support.ts測試 service 會先從-css-blocks-test-support-data中按 module 名查到 block 的運行時 guid再通過-css-blocks-data反查該 guid 下所有 interface 樣式名style()會校驗樣式名是否存在不存在時拋出包含可用樣式列表的錯誤。而classNamesFor()被覆寫為在真實運行時類名之前拼接一個由代理樣式名getStyleNames返回的人類可讀類名構成的前綴——這樣測試里斷言的就是接近源碼語義的可讀類名。示例來自 README 并補充完整import { setupCSSBlocksTest } from my-very-fine-app/services/css-blocks-test-support; module(Acceptance | css blocks test, function (hooks) { setupApplicationTest(hooks); setupCSSBlocksTest(hooks); test(visiting /, async function (assert) { await visit(/); let defaultBlock this.cssBlocks.getBlock(my-very-fine-app/styles/components/application, default); let element find([data-test-large-hello]); assert.ok(element.classList.contains(defaultBlock.style(:scope[sizelarge]))); }); });測試數(shù)據(jù)只在非生產(chǎn)構建生成見 broccoli-plugin.ts且只包含屬于本倉庫應用及所有 in-repo addon / in-repo engine的 block外部依賴 block 不會暴露在測試命名空間中。七、版本演進主線1.2.0 → 1.5.0結合 CHANGELOG可以把該 addon 的能力演進梳理為清晰的時間線7.1 1.2.02020-08-05運行時體系奠基這是功能最密集的版本確立了 addon 的核心架構FeatureEstablish ember-app addon建立本 addon 本體Basic runtime helper build infrastructure and scaffoldingBasic runtime style calculations workingImplied style runtime supportDeserializing block definition files analysis in the ember-appEnable optimizer and runtime rewriting of optimized stylesOptimized css in ember-app build outputCentralize ember config and use it in ember ember-app。Bug Fixes涵蓋聲明合并declaration merging重寫、繼承與組合inheritance/compositionbug、樣式需求滿足style requirements校驗、lazy engines 的兩輪 hack 修復Egregious hack to make lazy engines work 與 Slightly less hacky approach to working with lazy engines、只合并存在的app.css、在更多作用域中查找 broccoli 樹路徑、復用預編譯 CSS 并把編譯 CSS 交給優(yōu)化器、不合并輸出文件Dont merge if an output file is specified等。這一版本確立了模板樹編譯 → CSS 樹聚合 → 運行時數(shù)據(jù) 優(yōu)化 CSS的整體形態(tài)。7.2 1.3.02020-08-11運行時結構優(yōu)化FeatureEmit attribute groups in the runtime aggregate rewrite dataSimplify rewrite for dynamic attribute values。Bug FixesExtract StyleEvaluator, StyleResolver classes from runtime service把求值邏輯從 service 拆成獨立類即現(xiàn) runtime/app/services/StyleEvaluator.ts 與 StyleResolver.tsSometimes theres no css blocks output 的空輸出兜底。7.3 1.4.02020-09-04sourcemap 與拼接可定制FeatureEnd-to-end sourcemaps for ember v2 pipelineProvide ability to override concat settings即broccoliConcat選項的來源Update concatenationWIP sourcemaps fix。Bug Fixes拼寫修正brocolli → broccoli、PR 反饋跟進。7.4 1.5.02020-09-16沖突檢測與產(chǎn)物收斂FeatureScan app CSS for classesClass name collision detectionAdd fileloc to class name conflict error——即 4.4 節(jié)所述的后處理沖突檢測體系。Bug FixesPick up fix for opticss crash on unknown css declarations跟隨 opticss 修復未知 CSS 聲明崩潰Prune css-blocks.css from the output after concatenating it拼接后清理中間產(chǎn)物。八、常見注意事項Common GotchasREADME 中該節(jié)目前標注為 Nothing yet...但結合源碼與 CHANGELOG 可以總結出幾條實踐中確實存在的注意點必須同時安裝css-blocks/ember本 addon 只聚合與優(yōu)化編譯靠css-blocks/ember完成缺失時不會生成任何 CSS 輸出見 src/index.ts。output與自動拼接互斥設置output后 CSS Blocks 內(nèi)容不再自動并入app.css需自行 import。短類名沖突應用普通 CSS 中約 5 字符的短類名要加入appClasses否則優(yōu)化器可能復用它們導致構建期沖突檢測報錯見 broccoli-plugin.ts。setupCSSBlocksTest的調(diào)用順序必須在setupTest|setupRenderingTest|setupApplicationTest之后調(diào)用否則直接拋錯。broccoliConcat: false的后果拼接不會執(zhí)行必須自行把編譯產(chǎn)物并入最終 CSS。lazy engine使用css-blocks/ember的每個 engine 都要把css-blocksservice 加入依賴。九、小結css-blocks/ember-app是 CSS Blocks 在 Ember 應用側的最后一公里它把css-blocks/ember在模板樹中編譯出的內(nèi)容收攏、優(yōu)化、拼接為最終 CSS同時生成驅(qū)動模板運行時與測試環(huán)境的類名數(shù)據(jù)。理解它的七個配置項、三個階段JS 樹預處理 → CSS 樹預處理 → CSS 樹后處理以及運行時服務的求值鏈路是排障與深度定制的前提而 1.2.0 到 1.5.0 的演進軌跡恰好展示了這套架構從運行時奠基、結構優(yōu)化到?jīng)_突檢測與產(chǎn)物收斂的完整迭代路徑。贊分享前端構建工具【免費下載鏈接】css-blocksHigh performance, maintainable stylesheets.項目地址https://gitcode.com/gh_mirrors/cs/css-blocks點擊查看免費下載相關推薦css-blocks/ember 版本演進與實現(xiàn)剖析Ember 構建管線中的 CSS Blocks 集成css blocks/ember 版本演進與實現(xiàn)剖析Ember 構建管線中的 CSS Blocks 集成 css blocks/ember 是 CSS B前端構建工具css-blocks/ember 實戰(zhàn)指南在 Ember 應用中集成 CSS Blocks 構建管線css blocks/ember 實戰(zhàn)指南在 Ember 應用中集成 CSS Blocks 構建管線 CSS Blocks 是一套面向 Ember 應用的高前端構建工具css-blocks/ember-cli 演進史與實現(xiàn)原理CSS Blocks 的 Ember/Glimmer 構建集成全解析css blocks/ember cli 演進史與實現(xiàn)原理CSS Blocks 的 Ember/Glimmer 構建集成全解析 css blocks/em前端構建工具上一篇3種方案零基礎上手小愛音箱智能音樂系統(tǒng)安裝教程下一篇解鎖小愛音箱智能升級 煥新音樂體驗創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考