项目中通常会需要统一设置样式或者根据某种情况来定 width 和 height, 如何实现在 HTML,CSS, JS 中都能访问到的所谓共享变量呢? 其实都归功于
webpack
作者在阅读了
这篇文章
之后发现了使用JS 操作 CSS 代价十分昂贵, 会减慢 react 应用的渲染, 主要原因是在 react app 中,
react-with-styles
使用 runtime 的样式化后的组件会额外生成两个
Context.Consumer
以及一个
Provider
, 而这些额外的组件使得 CSS 可以监听到某些 JS 事件或者获取变量去更新样式
而静态的 CSS 不会
所以在少部分使用时还好, 但是如果是大规模使用, 比如在 table 中, 就会使得两者的性能差距变大. 但是呢, 谁不想用静态呢? 那不是产品经理有需求, 要动态的去更改啊.
以下方案就是避免了一部分情况下的 JSTOCSS 但并不是所有, 比如用户点击之后对 CSS 进行修改, 这时其实也尽量少的更改 CSS , 而是给组件添加 className, 那样至少省去了 CSS 树的重新构建过程.
设置 app
yarn init -y
安装打包工具 webpack
yarn add -D webpack webpack-cli
编辑
package.json
文件
"script"
: {
"build"
:
"webpack"
创建
globals.js
文件, 里面包含了我们需要跨文件类型去获取的变量
module.exports = {
myTitle: 'Hello dev.!',
myColor: '#42ff87'
创建 webpack.config.js打包配置文件
module.exports = {
entry: __dirname + '/app/index.js',
output: {
path: __dirname + '/dist',
filename: 'bundle.js'
创建一个 app文件夹, 包含 index.html, index.js.文件目录结构如下:
|-- node_modules/
|-- package.json
|-- webpack.config.js
|-- globals.js
|-- app/
|-- index.html
|-- index.js
先在 index.html中写些模板代码, 添加进变量 myTitle
<html lang="en">
<title>Webpack shared variables!</title>
</head>
<h1><%= myTitle %></h1>
</body>
</html>
安装html-webpack-plugin,
yarn add -D html-webpack-plugin
配置 webpack
const HTMLWebpackPlugin = require('html-webpack-plugin')
const globals = require('./globals.js')
module.exports = {
plugins: [
new HTMLWebpackPlugin({
template: 'app/index.html',
templateParameters: globals
执行yarn build就会发现生成的 index.html 中的 myTitle就被替换成了Hello dev.!. 其本质原理其实就是字符串模板.
在 js 中使用变量
这是最基本的了.
import globals from '../globals.js'
document.write(
`<pre>
${JSON.stringify(globals, null, 2)}
</pre>`
"myTitle": "Hello dev.to !",
"myColor": "#42ff87"
CSS 中的变量
其实在 CSS 中是无法直接使用全局变量的, 需要用到 SASS. 不过浏览器不认识 sass 这个格式, 需要使用几个 loader, 将其转换成 css.yarn add -D sass-loader css-loader style-loader
在 app/style.scss中写以下内容, 注意我们使用的是 scss 格式, 它与 sass 的唯一区别就是加不加括号
color: $myColor
color: $myColor
但是因为 scss 兼容所有 css3 以及本身就是 sass3 的新语法, 所以也支持 sass-loader, 所以在项目中一般都使用 scss
接下来需要将变量注入进去. sass-loader有一个prependData的属性, 不过接受的是一个字符串而不是变量的格式, 比如$myColor: red; myTitle: '...'
module.exports = {
module: {
rules: [
test: /\.s(ac)ss$/i,
use: [
"style-loader",
"css-loader",
loader: "sass-loader",
options: {
prependData: "$myColor: '#42ff87'"
如果像把 css 单独抽出来的话可以使用 mini-css-extract-plugin, yarn add -D mini-css-extract-plugin安装之后, 将 style-loader 替换成该插件的 loader 即可
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
test: /\.s(ac)ss$/i,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
loader: "sass-loader",
options: {
prependData: "$myColor: '#42ff87'"