reactjs - 如何使用 sass 为自定义 npm 包加载带有 webpack 的本地字体?
问题描述
背景:
为了或可重用性,我正在编写一个 NPM 包来存储样式化的反应组件。
我已经对组件进行了大部分样式化,但无法让那些继承存储在本地 npm 包中的正确字体。
NPM项目的文件夹结构:
- /dist
- /src
- /src/资产/
- /src/组件/
- /src/元素/
- /src/样式/
- /src/index.js
- /webpack.config.js
Webpack.config.js
var path = require('path');
const sass = require("node-sass");
const sassUtils = require("node-sass-utils")(sass);
const sassVars = require(__dirname + "/src/styles/theme.js");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
// Convert js strings to dimenssions
const convertStringToSassDimension = function(result) {
// Only attempt to convert strings
if (typeof result !== "string") {
return result;
}
const cssUnits = [
"rem",
"em",
"vh",
"vw",
"vmin",
"vmax",
"ex",
"%",
"px",
"cm",
"mm",
"in",
"pt",
"pc",
"ch"
];
const parts = result.match(/[a-zA-Z]+|[0-9]+/g);
const value = parts[0];
const unit = parts[parts.length - 1];
if (cssUnits.indexOf(unit) !== -1) {
result = new sassUtils.SassDimension(parseInt(value, 10), unit);
}
return result;
};
const dist = path.resolve(__dirname, 'dist');
const app = path.resolve(__dirname, 'src');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: dist,
filename: 'index.js',
libraryTarget: 'commonjs2' // THIS IS THE MOST IMPORTANT LINE! :mindblow: I wasted more than 2 days until realize this was the line most important in all this guide.
},
module: {
rules: [
// Javascript file loading
{
test: /\.js$/,
include: app,
exclude: /(node_modules|bower_components|dist)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{
test: /\.(scss|sass)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader' },
{
loader: "sass-loader?sourceMap",
options: {
functions: {
"get($keys)": function(keys) {
keys = keys.getValue().split(".");
var result = sassVars;
var i;
for (i = 0; i < keys.length; i++) {
result = result[keys[i]];
// Convert to SassDimension if dimenssion
if (typeof result === "string") {
result = convertStringToSassDimension(result);
} else if (typeof result === "object") {
Object.keys(result).forEach(function(key) {
var value = result[key];
result[key] = convertStringToSassDimension(value);
});
}
}
result = sassUtils.castToSass(result);
return result;
}
}
},
},
],
})
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[ext]'
}
}
]
},
plugins: [
new ExtractTextPlugin({ filename: '[name].css' })
]
};
src/index.js
import Header1 from './elements/Header1';
import Header2 from './elements/Header2';
import Header3 from './elements/Header3';
import Toggle from './elements/Toggle';
module.exports = {
Header1,
Header2,
Header3,
Toggle,
};
src/elements/Header1.js
import styled from 'styled-components';
import * as theme from '../styles/theme';
import '../styles/variables.scss';
const Header1 = styled.h1`
font-family: brownprott;
font-weight: bold;
font-size: 32px;
color: ${theme.colors.teal};
`;
export default Header1;
src/styles/variables.scss
@import 'typography.scss';
$colors: get("colors");
$white: #FFFFFF;
$teal: #00EBD0;
$lightGrey: #DADCDD;
$darkGrey: #222425;
$red: #FF0000;
$info: #1FB6FF;
$success: #13CE66;
$danger: #FF4949;
$warning: #FFC82C;
src/styles/typography.scss
$font_path: '~/assets/fonts/';
@font-face {
font-family: "brownprott";
src: url($font_path + "brownprott_light.ttf");
font-weight: "lighter";
}
@font-face {
font-family: "brownprott";
src: url($font_path + "brownprott_regular.ttf");
font-weight: "normal";
}
@font-face {
font-family: "brownprott";
src: url($font_path + "brownprott_italic.ttf");
font-weight: "normal";
font-style: "italic";
}
@font-face {
font-family: "brownprott";
src: url($font_path + "brownprott_bold.ttf");
font-weight: "bold";
}
现在,当我运行时,webpack --watch
我得到以下输出:
@npm-module-name@0.0.2 开始 /path/to/npm-module-name webpack --watch
Webpack is watching the files…
Hash: 549baa5760d8010ca491
Version: webpack 4.8.3
Time: 1148ms
Built at: 2018-05-25 11:29:58
Asset Size Chunks Chunk Names
index.js 55.7 KiB 0 [emitted] main
main.css 504 bytes 0 [emitted] main
Entrypoint main = index.js main.css
[2] ./src/styles/theme.js 373 bytes {0} [built]
[11] ./src/elements/Toggle.js 4.42 KiB {0} [built]
[12] ./src/elements/Header3.js 1.17 KiB {0} [built]
[13] ./src/elements/Header2.js 1.17 KiB {0} [built]
[21] (webpack)/buildin/harmony-module.js 597 bytes {0} [built]
[23] ./src/elements/Header1.js 1.16 KiB {0} [built]
[24] ./src/index.js 630 bytes {0} [built]
[28] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js??ref--5-3!./src/styles/variables.scss 712 bytes [built]
[29] ./src/styles/variables.scss 41 bytes [built]
+ 21 hidden modules
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/index.js!node_modules/sass-loader/lib/loader.js??ref--5-3!src/styles/variables.scss:
Entrypoint undefined = extract-text-webpack-plugin-output-filename
[1] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js??ref--5-3!./src/styles/variables.scss 712 bytes {0} [built]
+ 1 hidden module
并生成以下文件:
- dist/index.js
- main.css
当我将此 npm 包导入我的另一个项目时,我得到:
关于如何确保我正在处理的项目能够成功加载 NPM 包中的字体并让那些通过使用的项目看到的字体的任何帮助/说明,那就太好了!
谢谢你。
解决方案
推荐阅读
- javascript - 'sed' 命令不适用于 java 脚本
- python - 尝试从 Azure VM 连接到 Azure 托管实例中的 sql 时超时
- google-sheets - 将两个连接的表合并为一个图形
- java - Java 8 到 Java 11 迁移中的单元测试失败
- java - Java:线程划分为块数组 - 执行器服务
- python - LSTM 模型在评估期间没有任何差异
- search - 你如何使用 vim-extension 在 vscode 中显示搜索文本?
- python - 在python中解析子/孙
- java - Java 静态到 Kotlin 的转换
- docker - Redis 将数据存储在 backup.db 文件中