Сообщество React изучает различные JSS-решения, такие как хорошо известный теперьstyled-components
, но у всех у них есть какие-то проблемы в большей или меньшей степени, но исследование сообществом JSS-решений не прекратилось, и лучшим решением сейчас кажется библиотека Linaria. Пролистав эту библиотеку, я почти не нашел информации на китайском языке, связанной с этой библиотекой, поэтому я написал эту статью, чтобы поделиться с вами соответствующим контентом и представить его.
представлять
Линария — этонулевое время выполненияФреймворк JSS, его особенности:
- Внедрить CSS в систему JS, и эта поддержка предоставляется бесплатно! Код, связанный с CSS, будет извлечен в файл CSS во время компиляции.
- Sass-подобный синтаксис CSS
- Linaria поддерживает быстрое создание компонентов в стиле React с динамическими свойствами с помощью переменных CSS.
- Использование исходных карт CSSЛегко найти местоположение стиля
- поддержка стилета
- Препроцессор больше не нужен, вы можетеИспользуйте логику для управления CSS JavaScript
- ноПоддерживает использование препроцессоров, такие как Sass или PostCSS
Преимущества перед традиционными решениями CSS
1. Стилевая изоляция
const title = css`
font-size: 18px;
`;
Подобный код в конечном итоге будет скомпилирован в
.k4yi6fg {
font-size: 18px;
}
Его имя класса определяется путем вычисления хеш-значения пути к файлу.
2. Стили и компоненты принадлежат одному и тому же файлу
Больше не будет переключений контекста, которые требуют перехода между файлами JS и файлами CSS при написании компонентов. Но если вы хотите разделить, это также поддерживается
3. Надежная и безопасная поддержка рефакторинга
Поскольку стили JSS на самом деле являются просто переменными JS, вы можете легко найти логику стиля, связанную с компонентом, через логику кода, не опасаясь, что рефакторинг вызовет неожиданные эффекты.
4. Препроцессор больше не нужен
Самое интересное в JSS заключается в том, что когда вы приписываете CSS JS, вы автоматически получаете возможность писать логику CSS на JS, самые простые условные вычисления и сложную логику, заключенную в простые вызовы функций. Это означает, что верхний предел выразительной силы CSS больше не ограничивается собой, а определяется JS.
Например, вы можете написать такой код
const DEFAULT_COLOR = '#fffff'
const PRIMARY_COLOR = '#de2d68';
const getColor = Math.random() > 0.5 ? PRIMARY_COLOR : DEFAULT_COLOR;
const button = css`
background-color: ${getColor()};
&:hover {
background-color: ${Math.random() > 0.5 ? PRIMARY_COLOR : DEFAULT_COLOR};
}
`;
5. Tree shaking
Как мы только что сказали, JSS на самом деле просто переменная JS, поэтому, естественно, то, что JS может делать встряхивание дерева, Linaria может делать то же самое. Это на самом деле очень привлекательно для разработчиков UI-библиотек: больше не нужно вводить дополнительные плагины babel, а автоматически вводятся стили по запросу через встряхивание дерева.
6. Автоматически добавлять префиксы браузера
Linaria автоматически добавит префиксы браузера, чтобы помочь вам поддерживать некоторые специальные свойства для совместимости, и вы по-прежнему можете использовать PostCSS для дальнейшей оптимизации.
7. Возможность декларативно и динамически стилизовать компоненты React.
пройти черезstyled
API для простого объявления компонентов React с динамическим стилем. Принцип заключается в достижении возможности автоматического обновления стилей компонентов с помощью переменных CSS, в то время как обычные решения CSS требуют, чтобы вы поддерживали соответствующую логику вручную.
const Box = styled.div`
background-color: orange;
height: ${props => props.size}px;
width: ${props => props.size}px;
`;
<Box size={48}>
Преимущества перед препроцессорами CSS
1. Никаких новых затрат на обучение
Синтаксис Linaria можно рассматривать как просто поддерживающий вложенный синтаксис CSS. Никаких переменных, примесей или функций, их можно заменить логикой JS.
2. Преимущества перед традиционными схемами CSS одинаковы для препроцессоров CSS.
Преимущества перед написанием встроенных стилей напрямую
1. Полная поддержка возможностей CSS
Встроенные стили имеют ограничения, а Linaria поддерживает все возможности CSS:
- запросы средств массовой информации
- CSS3 анимация
- псевдокласс, псевдоэлемент
2. Преимущества производительности
Применение стилей с помощью именования классов выполняется быстрее, чем встроенные стили.
Преимущества перед другими решениями JSS
1. CSS загружается и парсится отдельно от JS
Поскольку CSS-файл извлекается компилятором в файл CSS, браузер может загружать файлы CSS и JS параллельно, что ускоряет время в верхней части страницы.
2. Никаких дополнительных затрат на парсинг
Многие JSS-фреймворки используют сторонние JS-библиотеки для анализа строк CSS. Необходимость включения синтаксического анализатора увеличит размер библиотеки. А анализ и выполнение CSS откладывается до времени выполнения JS, На некоторых недорогих устройствах легко вызвать ощутимую задержку.
Линария в нем особеннаянет времени выполненияТем не менее, его стили будут анализироваться и извлекаться во время компиляции для создания файлов CSS, которые не нужно дополнительно анализировать во время выполнения.
3. Нет потери производительности за повторный рендеринг во время SSR.
Для JSS-фреймворков, основанных на компонентах, рендеринг одного и того же компонента с разными реквизитами приведет к тому, что один и тот же стиль будет копироваться несколько раз, что увеличивает размер продукта во время SSR. Хотя в большинстве случаев о снижении производительности из-за этой проблемы не стоит упоминать, при отображении множества больших списков с небольшими различиями размер легко увеличивается.
Кроме того, при выполнении SSR нужно извлекать CSS-стиль, записанный в JS-файле, а затем передавать его в браузер, что также увеличивает объем продукта.
Linaria будет генерировать уникальные правила стиля и использовать переменные CSS для применения различных различий, поэтому не будет проблем с повторяющимися стилями, что уменьшит размер продукта.
4. Проверка времени компиляции на наличие синтаксических ошибок
Недопустимые значения JS и неправильный синтаксис CSS проверяются во время компиляции, а не обнаруживаются во время выполнения. Это означает, что вы не столкнетесь с этими низкоуровневыми ошибками в производственном режиме, а также, Linaria поддерживает stylelint, и вы все еще можете получить тот же опыт работы с lint, что и раньше.
5. Знакомый синтаксис CSS
В отличие от некоторых других фреймворков JSS, синтаксис Linaria поддерживает только вложенный нативный синтаксис CSS, и для начала работы не требуется никаких затрат. Идеальная поддержка программирования Copy-Paste
6. Поддерживает работу без JavaScript
Если ваш веб-сайт должен работать с отключенным JavaScript или если вы хотите скомпилировать статические страницы, Linaria также может работать в этих ситуациях, потому что еенет времени выполненияхарактеристика
Конфигурация установки
Linaria поддерживает Webpack, Rollup и Sevlte одновременно. В этой статье будет описано только, как использовать его с Webpack. Если у вас есть другие потребности, вы можете перейти на официальный сайт, чтобы увидеть документацию для других инструментов сборки.
первый
Если вы используете Babel для транспиляции или полифилла в своем проекте, вы должны создать конфигурационный файл Babel под корневым проектом, и прописать в нем нужные пресеты и плагины, иначе Linaria не сможет разобрать ваш код
Работа с вебпаком
С Webpack легко работать, просто добавьте babel-loaderlinaria/loader
Да, убедитесьlinaria/loader
рядом с и после babel-loader
{
test: /\.js$/,
use: [
{ loader: 'babel-loader' },
{
loader: 'linaria/loader',
options: {
sourceMap: process.env.NODE_ENV !== 'production',
},
}
],
}
Также для извлечения собранных стилей нужен еще один плагин Webpackmini-css-extract-plugin
, воплощать в жизньnpm i -D css-loader mini-css-extract-plugin
установить
затем импортироватьmini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
Затем установите соответствующие правила парсинга и плагины
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV !== 'production',
},
},
{
loader: 'css-loader',
options: {
sourceMap: process.env.NODE_ENV !== 'production',
},
},
],
},
Пучокmini-css-extract-plugin
Добавлено в конфиг Webpackplugins
атрибут
new MiniCssExtractPlugin({
filename: 'styles.css',
});
ты можешь пройтиHTMLWebpackPlugin
Плагин для связывания извлеченного файла CSS с файлом html, сгенерированным сборкой. Для режима производства вам может потребоваться установить значение хеш-функции для имени файла CSS:
new MiniCssExtractPlugin({
filename: 'styles-[contenthash].css',
});
Потому что Linaria будет проходить через Webpack с извлеченными файлами стилей..css
Обычный конвейер загрузчика, так что вы можете легко использоватьpostcss
илиclean-css
сделать некоторые настройки
Полный пример конфигурации Webpack
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const dev = process.env.NODE_ENV !== 'production';
module.exports = {
mode: dev ? 'development' : 'production',
devtool: 'source-map',
entry: {
app: './src/index',
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
filename: '[name].bundle.js',
},
optimization: {
noEmitOnErrors: true,
},
plugins: [
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV) },
}),
new MiniCssExtractPlugin({ filename: 'styles.css' }),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
{
loader: 'linaria/loader',
options: { sourceMap: dev },
},
],
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV !== 'production',
},
},
{
loader: 'css-loader',
options: { sourceMap: dev },
},
],
},
{
test: /\.(jpg|png|gif|woff|woff2|eot|ttf|svg)$/,
use: [{ loader: 'file-loader' }],
},
],
},
devServer: {
contentBase: [path.join(__dirname, 'public')],
historyApiFallback: true,
},
};
Вы можете установить все необходимые библиотеки npm с помощью следующей команды
npm i -D webpack webpack-cli webpack-dev-server mini-css-extract-plugin css-loader file-loader babel-loader
Настройте свойство options linaria/loader
Вы можете передать свойство options, подобное этому
{
loader: 'linaria/loader',
options: {
sourceMap: false, // 是否产生 CSS source map,默认 false
cacheDirectory: '.linaria-cache', // 缓存所在文件见,默认 .linaria-cache
extension: '.linaria.css', // CSS 文件处于中间态时的命名,默认 .linaria.css
preprocessor: 'stylis', // 定义 css 的预处理器,默认为 stylis
},
}
Как использовать
Linaria очень проста в использовании, есть только один основной метод `css```, который в принципе может покрыть все сценарии. В то же время он также предоставляет некоторые вспомогательные функции с синтаксическим сахаром для удобства разработки.
API браузера
css
```
css
Являетсяфункция метки, что означает, что вы можете передать строку шаблона ```` вместо()
для вызова этой функции результат оценки функции метки будет преобразован плагином Babel в уникальное имя класса.
import { css } from 'linaria';
const flower = css`
display: inline;
color: violet;
`;
// flower === flower__9o5awv –> with babel plugin
Любые стили CSS, записанные в строке шаблона, будут ограничены соответствующим именем класса, включая медиа-запросы и анимацию. Мы можем объявить анимацию следующим образом:
import { css } from 'linaria';
const box = css`
animation: rotate 1s linear infinite;
@keyframes rotate {
{ from: 0deg; }
{ to: 360deg; }
}
`;
cx(...classNames: Array<string | false | void | null | 0>) => string
cx()
Объединяет входящую строку, но игнорирует ееFalsy
значение, например''
,null
а такжеundefined
Ждать
import { css, cx } from 'linaria';
const cat = css`
font-weight: bold;
`;
const yarn = css`
color: violet;
`;
const fun = css`
display: flex;
`;
function App({ isPlaying }) {
return <Playground className={cx(cat, yarn, isPlaying && fun)} />;
}
cx()
Эта функция очень похожа на популярную библиотекуclassnames
, но отличия все же естьcx()
Объект не обработан
styled
Вспомогательный объект для быстрого создания компонентов React, он используется какstyled-components
:
styled
как использовать иcss
Очень похоже, за исключением того, что вы можете вставлять функции в строку шаблона, чтобы получить свойства компонента и динамически устанавливать стили.
import { styled } from 'linaria/react';
import colors from './colors.json';
const Container = styled.div`
background-color: ${colors.background};
color: ${props => props.color};
width: ${100 / 3}%;
border: 1px solid red;
&:hover {
border-color: blue;
}
`;
Точно так же все правила стиля локализованы. Чтобы избежать повторения кода стиля CSS, мы можем ссылаться на другие стили, подобные этому.
const Title = styled.h1`
font-size: 36px;
`;
const Article = styled.article`
font-size: 16px;
/* this will evaluate to the selector that refers to `Title` */
${Title} {
margin-bottom: 24px;
}
`;
И мы можем пройтиas
атрибут, чтобы указать, что на самом деле отображает HTML-тег
// Here `Button` is defined as a `button` tag
const Button = styled.button`
background-color: rebeccapurple;
`;
// You can switch it to use an `a` tag with the `as` prop
<Button as="a" href="/get-started">
Click me
</Button>;
styled
Также поддерживает вложение стилей в виде компонентов более высокого порядка.
const Button = styled.button`
background-color: rebeccapurple;
`;
// The background-color in FancyButton will take precedence
const FancyButton = styled(Button)`
background-color: black;
`;
API сервера (linaria/server
)
collect(html: string, css: string) => string
При выполнении SSR нам нужно не только вернуть соответствующий HTML-код, но ипотребностикод стиля возвращается, вот и всеКлючевойКод CSS, мы можем использоватьcollect()
функция для извлечения ключевого кода CSS
import { collect } from 'linaria/server';
const css = fs.readFileSync('./dist/styles.css', 'utf8');
const html = ReactDOMServer.renderToString(<App />);
const { critical, other } = collect(html, css);
// critical – returns critical CSS for given html
// other – returns the rest of styles
collect()
В соответствии с атрибутом класса элемента будет извлечен используемый код CSS, чтобы его можно было вернуть с помощью html.
Следует отметить, что порядок извлеченных селекторов кода CSS будет перепутан, что делает, если ваши стили зависят от веса порядка селектора, могут возникнуть непредвиденные ошибки, но поскольку имена классов, сгенерированные Linaria, все названы уникальными. , так что этой проблемы вообще не возникает, но на это нужно обращать внимание при работе с другими библиотеками
предупреждать
Linaria основана на переменных CSS.Большинство современных браузеров поддерживают эту функцию, но для IE 11 и ниже она не поддерживается, поэтому, если вам нужна поддержка IE 11, возможно, Linaria не лучший выбор.
следовать за
linaria/lader
был переименован@linaria/webpack4-loader