linaria 是乙個近似於styled-components
和emotion
jss 框架,不同點在於,styled-components
和emotion
是乙個執行時方案,而 linaria 是乙個編譯期 + 執行時方案。
執行時的 jss 方案必須內建乙個 css 處理器,並且在執行時去解析,分別增加了體積和效能上的成本。 linaria 創造性的在編譯期將相應的 jss 解析出來,抽出解壓到乙個 css 檔案中,並將相應的 jss **替換成乙個指向某個 css 類名的字串,避免了執行時方案的問題。
本文只做原理**,使用介紹相關請看 《linaria 也許是現在 react 最佳的 jss 方案》
對於以下**
import from '@linaria/core'
let size = 5;
size = (function() ());
const headerclassname = css`
text-align: center;
color: #fff;
`;const headertitleclassname = css`
.$ px;
}`;console.log(headerclassname, headertitleclassname);
linaria 會將其編譯為
// index.bundle.js
var size = 5;
size = function () ();
var headerclassname = "hf71da1";
var headertitleclassname = "hi1y09m";
console.log(headerclassname, headertitleclassname);
/* index.css */
.hf71da1
.hi1y09m .hf71da1
通過編譯後的**我們可以看出:
linaria 的實現依賴於 wbepack(rollup) 和 babel 是必然的,使用 linaria 必須在 webpack 和 babel 分別設定@linaria/webpack4-loader
和@linaria/babel
才可以。
通過webpack
使用 linaria 需要.rules
上進行如下配置
,
所有的 js **都會經過@linaria/webpack4-loader
,其核心**如下
export default function index(
this: loadercontext,
sourcecodes: string,
inputsourcemap: rawsourcemap | null
) );
if (result.csstext) = result;
if (sourcemap) */`;
}if (result.dependencies?.length) catch (e) `, e);
}});
}this.callback(
null,
`$\n\nrequire($);`,
result.sourcemap ?? undefined
);return;
}
是乙個標準的 webpack 非同步 loader ,@linaria/webpack4-loader
做的事情就是把傳入的源**當做引數傳入、呼叫transform
函式,這個函式來自@linaria/babel
,@linaria/babel
是 linaria 維護的解析 jss **的babel-preset
。
export default function transform(code: string, options: options): result ;
} // ...
const ast = parsesync(code, ,
});const = transformfromastsync(
ast!,
code,
//.....
)!;const = (metadata as babel.babelfilemetadata & ).linaria;
let csstext = '';
object.keys(rules).foreach((selector, index) => ,
original: rules[selector].start!,
name: selector,
source: '',
});// run each rule through stylis to support nesting
csstext += `$\n`;
});return ;
}
transform
內部首先會判斷**是否使用 linaria 的 api ,如果使用了則解析相應的 jss **,**並執行相關的 js **,**這也是為什麼本文開頭例子處編譯後樣式表的font-size
的值為 3 而非 5 的原因。解析的時候,@linaria/babel
會將 jss 中的 css **寫到metadata
裡,而非轉化後的源**處,隨後交付給@linaria/webpack4-loader
處理。
metadata
是 babel 解析、轉譯**時用於儲存一些輔助資訊的地方,其內容適用於輔助轉譯流程的,轉譯完成後就不存在了
也就是說,@linaria/babel
只負責將 jss **根據檔案路徑計算出乙個雜湊名,作為類名,替換相應的jss **。 css 解壓相關的操作由@linaria/webpack4-loader
負責。
@linaria/webpack4-loader
會將metadata
裡 css 解壓到.linaria-cache/index.linaria.css
裡,然後在轉化後的源**末尾處加上require("./.linaria-cache/index.linaria.css")
,隨後 webpack 解析時就會將解析.css
檔案相關操作委託到處理.css
檔案的 loader ,此時我們可以自由選擇使用mini-css-extract-plugin
還是style-loader
,或者其他的.css
loader ,重點在於我們擁有了webpack
和.css
檔案相關的生態,而其他的 jss 方案就沒法做到這點。
js **經由@linaria/webpack4-loader
@linaria/webpack4-loader
內部使用@linaria/babel
解析、執行 js **
@linaria/babel
將 jss 編譯成根據檔案路徑生成的類名,將 css **寫入到生成的metadata
,將其交付到@linaria/webpack4-loader
@linaria/webpack4-loader
將metadata
的 css **解壓到/.linaria-cache
檔案中
@linaria/webpack4-loader
在解析後**末尾處加上require("./.linaria-cache/index.linaria.css")
,交由 webpack 進行後續的處理
關於編譯型和解釋型
編譯型 編譯型 complie 將j a程式中的源 翻譯成計算機能看懂的語言,然後執行 編譯器做這事 就好像你看一本外國的翻譯書,翻譯一遍,你就可以一直看,如果這本書更新了,你就需要重新購買這本書的翻譯版。但編譯型的程式不可以跨平台,簡單理解 就是這本書原本是俄文翻譯成了中文,你給乙個美國人他能看懂...
後台T型框架
這段時間主要是開始涉及一下後端,起碼要做到能懂大部分。懂後端和不懂後端做專案肯定不一樣 在這裡主要是記錄一下,防止學的不好卻自我感覺很ok!1 後台介面主要是由 t 型組成。在 frameset 之中示意圖 舉例 frameset.html lang en charset utf 8 framese...
編譯型語言與解釋型語言
計算機是不能理解高階語言的,更不能直接執行高階語言,它只能直接理解機器語言,所以使用任何高階語言編寫的程式若想被計算機執行,都必須將其轉換成計算機語言,也就是機器碼。而這種轉換的方式有兩種 1 編譯 2 解釋 由此高階語言也分為編譯型語言和解釋型語言。一 編譯型語言 使用專門的編譯器,針對特定的平台...