获取字体的版本化字符串名称
Get versioned string name of font
)
我想预取我使用 Tailwindcss 生成的字体。
我是这样添加字体的:
@layer base {
/* lato-300 - latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 300;
src: local('Lato Light'), local('Lato-Light'),
url('../fonts/lato-v16-latin-300.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-300.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-300.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-300.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
/* lato-300italic - latin */
@font-face {
font-family: 'Lato';
font-style: italic;
font-weight: 300;
src: local('Lato Light Italic'), local('Lato-LightItalic'),
url('../fonts/lato-v16-latin-300italic.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-300italic.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-300italic.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-300italic.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
}
现在我使用 Laravel-mix:
处理我的 css
const {EnvironmentPlugin} = require ('webpack');
const mix = require ('laravel-mix');
const glob = require ('glob');
const path = require ('path');
const {CleanWebpackPlugin} = require ('clean-webpack-plugin');
const ChunkRenamePlugin = require ('webpack-chunk-rename-plugin');
const TargetsPlugin = require('targets-webpack-plugin');
require ('laravel-mix-tailwind');
require('laravel-mix-polyfill');
require('laravel-mix-brotli');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.webpackConfig ({
output: {
chunkFilename: 'js/chunks/[name].[chunkhash].js'
},
plugins: [
new CleanWebpackPlugin ({
cleanOnceBeforeBuildPatterns: ['js/chunks/**/*']
}),
new EnvironmentPlugin ({
BASE_URL: '/'
}),
new ChunkRenamePlugin ({
initialChunksWithEntry: true,
'/js/app': 'js/app.js',
'/js/vendor': 'js/vendor.js',
}),
],
module: {
rules: [
{
test: /node_modules(?:\/|\).+\.js$/,
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {targets: 'last 2 versions, ie >= 10'}]],
plugins: ['@babel/plugin-transform-destructuring', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-transform-template-literals'],
babelrc: false
}
},
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/
}
]
},
resolve: {
alias: {
'@': path.join (__dirname, 'resources'),
'node_modules': path.join (__dirname, 'node_modules')
}
},
});
mix.js ('resources/js/app.js', 'public/js')
.postCss ('resources/css/app.css', 'public/css')
.tailwind ('./tailwind.config.js');
if (mix.inProduction ()) {
mix
.version ()
.polyfill({
enabled: true,
useBuiltIns: "usage",
targets: "> 0.25%, not dead",
corejs: 3
})
.brotli();
}
这是我处理后的 css 的样子:
@font-face {
font-family: 'Lato';
font-style: italic;
font-weight: 300;
src: local('Lato Light Italic'), local('Lato-LightItalic'),
url(/fonts/lato-v16-latin-300italic.woff2?a21767e20d27a9c06007c981a8e5f827) format('woff2'), url(/fonts/lato-v16-latin-300italic.woff?8e90b967ea69fc68b130d36cc34d41c0) format('woff'), url(/fonts/lato-v16-latin-300italic.ttf?329d60785944501134891f948f41c001) format('truetype'), url(/fonts/lato-v16-latin-300italic.svg?17e346950dce164549968b7b93d48f2d#Lato) format('svg'); /* Legacy iOS */
font-display: swap;
}
不知何故,我需要找到一种方法将那些版本化的字体调用包含到我的预取中。
我的第一次尝试是遍历 public/fonts
中的所有文件,但当然我没有得到版本 url:
@foreach(File::files(public_path('fonts')) as $font)
<link rel="preload" href="/fonts/{{$font->getFilename()}}" as="font">
@endforeach
我的一个想法是将 url 添加到 mix-manifest.json
,但我有点卡在这里了:-(
我不太确定你想要什么,所以这里有两个选择:
这将停止处理 URL,保留字体
.options({
processCssUrls: false,
})
您可以在 CSS 中使用它来保留字体
@import url('https://fonts.googleapis.com/css2?family=Rowdies:wght@300&display=swap');
唯一的问题是,如果字体是来自 css 的自定义字体,您可能需要为要从
调用的字体创建网站
如果有足够的上下文,可能会有更好的方法来解决您要解决的潜在问题,但是在您已有的基础上,我接下来会创建一个辅助函数:
function fontVersion($filename){
$source = file_get_content(public_path('css/app.css'));
$start = strpos($source, $filename) + strlen($filename);
$end = strpos($source, ')', $start);
return substr($source, $start, $end - $start);
}
然后在我的视图中调用它以将版本字符串添加到我的 URL:
@foreach(File::files(public_path('fonts')) as $font)
<link rel="preload" href="/fonts/{{ $font->getFilename() . fontVersion(filename) }}" as="font">
@endforeach
这里是live demo稍作修改供您参考。
所以这是一种更简洁的方法。您可以获取 webpack.mix.js 中的资产列表并生成您的预加载代码:
mix.then((stats) => {
let preload = [];
for (let file of Object.keys(stats.compilation.assets)) {
if (file.indexOf("woff2") == -1) {
continue;
}
preload.push(`<link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin></link>`);
}
fs.writeFileSync("public/preload.txt", preload.join("\n"));
});
将其包含在您的 blade 中。
<?php @include public_path('preload.txt'); ?>
)
我想预取我使用 Tailwindcss 生成的字体。
我是这样添加字体的:
@layer base {
/* lato-300 - latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 300;
src: local('Lato Light'), local('Lato-Light'),
url('../fonts/lato-v16-latin-300.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-300.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-300.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-300.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
/* lato-300italic - latin */
@font-face {
font-family: 'Lato';
font-style: italic;
font-weight: 300;
src: local('Lato Light Italic'), local('Lato-LightItalic'),
url('../fonts/lato-v16-latin-300italic.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-300italic.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-300italic.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-300italic.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
}
现在我使用 Laravel-mix:
处理我的 cssconst {EnvironmentPlugin} = require ('webpack');
const mix = require ('laravel-mix');
const glob = require ('glob');
const path = require ('path');
const {CleanWebpackPlugin} = require ('clean-webpack-plugin');
const ChunkRenamePlugin = require ('webpack-chunk-rename-plugin');
const TargetsPlugin = require('targets-webpack-plugin');
require ('laravel-mix-tailwind');
require('laravel-mix-polyfill');
require('laravel-mix-brotli');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.webpackConfig ({
output: {
chunkFilename: 'js/chunks/[name].[chunkhash].js'
},
plugins: [
new CleanWebpackPlugin ({
cleanOnceBeforeBuildPatterns: ['js/chunks/**/*']
}),
new EnvironmentPlugin ({
BASE_URL: '/'
}),
new ChunkRenamePlugin ({
initialChunksWithEntry: true,
'/js/app': 'js/app.js',
'/js/vendor': 'js/vendor.js',
}),
],
module: {
rules: [
{
test: /node_modules(?:\/|\).+\.js$/,
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {targets: 'last 2 versions, ie >= 10'}]],
plugins: ['@babel/plugin-transform-destructuring', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-transform-template-literals'],
babelrc: false
}
},
{
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/
}
]
},
resolve: {
alias: {
'@': path.join (__dirname, 'resources'),
'node_modules': path.join (__dirname, 'node_modules')
}
},
});
mix.js ('resources/js/app.js', 'public/js')
.postCss ('resources/css/app.css', 'public/css')
.tailwind ('./tailwind.config.js');
if (mix.inProduction ()) {
mix
.version ()
.polyfill({
enabled: true,
useBuiltIns: "usage",
targets: "> 0.25%, not dead",
corejs: 3
})
.brotli();
}
这是我处理后的 css 的样子:
@font-face {
font-family: 'Lato';
font-style: italic;
font-weight: 300;
src: local('Lato Light Italic'), local('Lato-LightItalic'),
url(/fonts/lato-v16-latin-300italic.woff2?a21767e20d27a9c06007c981a8e5f827) format('woff2'), url(/fonts/lato-v16-latin-300italic.woff?8e90b967ea69fc68b130d36cc34d41c0) format('woff'), url(/fonts/lato-v16-latin-300italic.ttf?329d60785944501134891f948f41c001) format('truetype'), url(/fonts/lato-v16-latin-300italic.svg?17e346950dce164549968b7b93d48f2d#Lato) format('svg'); /* Legacy iOS */
font-display: swap;
}
不知何故,我需要找到一种方法将那些版本化的字体调用包含到我的预取中。
我的第一次尝试是遍历 public/fonts
中的所有文件,但当然我没有得到版本 url:
@foreach(File::files(public_path('fonts')) as $font)
<link rel="preload" href="/fonts/{{$font->getFilename()}}" as="font">
@endforeach
我的一个想法是将 url 添加到 mix-manifest.json
,但我有点卡在这里了:-(
我不太确定你想要什么,所以这里有两个选择:
这将停止处理 URL,保留字体
.options({
processCssUrls: false,
})
您可以在 CSS 中使用它来保留字体
@import url('https://fonts.googleapis.com/css2?family=Rowdies:wght@300&display=swap');
唯一的问题是,如果字体是来自 css 的自定义字体,您可能需要为要从
调用的字体创建网站如果有足够的上下文,可能会有更好的方法来解决您要解决的潜在问题,但是在您已有的基础上,我接下来会创建一个辅助函数:
function fontVersion($filename){
$source = file_get_content(public_path('css/app.css'));
$start = strpos($source, $filename) + strlen($filename);
$end = strpos($source, ')', $start);
return substr($source, $start, $end - $start);
}
然后在我的视图中调用它以将版本字符串添加到我的 URL:
@foreach(File::files(public_path('fonts')) as $font)
<link rel="preload" href="/fonts/{{ $font->getFilename() . fontVersion(filename) }}" as="font">
@endforeach
这里是live demo稍作修改供您参考。
所以这是一种更简洁的方法。您可以获取 webpack.mix.js 中的资产列表并生成您的预加载代码:
mix.then((stats) => {
let preload = [];
for (let file of Object.keys(stats.compilation.assets)) {
if (file.indexOf("woff2") == -1) {
continue;
}
preload.push(`<link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin></link>`);
}
fs.writeFileSync("public/preload.txt", preload.join("\n"));
});
将其包含在您的 blade 中。
<?php @include public_path('preload.txt'); ?>