使用 webpack 构建 .scss 时忽略某些文件(字体)

时间:2021-07-19 09:58:31

标签: css webpack sass build fonts

示例目录结构如下所示:

当前:

example/
├── src/
│   ├── fonts/
│   │   └── OpenSans/
│   │       ├── OpenSans-Regular.woff
│   │       └── ...
│   ├── js/
│   │   └── ...
│   ├── css/
│   │   ├── base/
│   │   │   ├── _font.scss
│   │   │   └── ...
│   │   └── ...
│   ├── app.js
├── web/
│   ├── build/
│   │   ├── fonts/
│   │   │   ├── OpenSans-Regular.woff
│   │   │   └── ...
│   │   ├── app.css
│   │   ├── app.es5.js
│   │   └── app.js
│   └── index.php
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js

目标:

example/
├── src/
│   ├── js/
│   │   └── ...
│   ├── css/
│   │   ├── base/
│   │   │   ├── _font.scss
│   │   │   └── ...
│   │   └── ...
│   ├── app.js
├── web/
│   ├── build/
│   │   ├── app.css
│   │   ├── app.es5.js
│   │   └── app.js
│   ├── fonts/
│   │   └── OpenSans/
│   │       ├── OpenSans-Regular.woff
│   │       └── ...
│   └── index.php
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js

我现在需要参考浏览器最终如何需要这些字体文件。这可能看起来像:

_font.scss

当前:

@font-face {
    font-family: 'Open Sans';
    src: url('../../fonts/OpenSans/OpenSans-Regular.eot');
    src: local('Open Sans Regular'), local('OpenSans-Regular'),
         url('../../fonts/OpenSans/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
         url('../../fonts/OpenSans/OpenSans-Regular.woff2') format('woff2'),
         url('../../fonts/OpenSans/OpenSans-Regular.woff') format('woff'),
         url('../../fonts/OpenSans/OpenSans-Regular.ttf') format('truetype'),
         url('../../fonts/OpenSans/OpenSans-Regular.svg#OpenSans-Regular') format('svg');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

目标:

@font-face {
    font-family: 'Open Sans';
    src: url('/fonts/OpenSans/OpenSans-Regular.eot');
    src: local('Open Sans Regular'), local('OpenSans-Regular'),
         url('/fonts/OpenSans/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
         url('/fonts/OpenSans/OpenSans-Regular.woff2') format('woff2'),
         url('/fonts/OpenSans/OpenSans-Regular.woff') format('woff'),
         url('/fonts/OpenSans/OpenSans-Regular.ttf') format('truetype'),
         url('/fonts/OpenSans/OpenSans-Regular.svg#OpenSans-Regular') format('svg');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

显然,我可以将字体文件放在源文件夹中并将它们包含在构建中(这是目前的情况),但这是不必要的。此外,从项目根目录中引用与 scss 文件相关的字体文件或绝对文件,但这只是将文件复制到 build/ 文件夹。这使得构建不必要地更长和更重。

我只是想把 url 放在 scss 文件中,构建过程应该简单地复制值,没有解析,没有改变,什么都没有,只是复制。

有关更多上下文,以下是当前的 webpack 文件:

webpack.common.js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const del = require('del');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');

/*
 * https://github.com/chrisblossom/clean-self-webpack-plugin
 * Remove project files before webpack is loaded.
 * Be sure it is not async.
 *
 * It is HIGHLY recommended to handle the initial
 * build directory clean outside of this plugin / webpack.
 *
 * Popular existing packages:
 * https://github.com/isaacs/rimraf
 * https://github.com/sindresorhus/del
 *    -- I prefer this one, great glob support and has CLI (del-cli package)
 * https://github.com/jprichardson/node-fs-extra
 */
del.sync([path.resolve(__dirname, 'web', 'build', '**/*')]);

exports.common = {
    entry: {
        app: './src/app.js',
        styleguide: './src/styleguide.js',
    },
    output: {
        path: path.resolve(__dirname, 'web', 'build'),
        publicPath: '/build/',
    },
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/i,
                use: [
                    // This plugin extracts CSS into separate files.
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {},
                    },
                    // Translates CSS into CommonJS
                    {
                        loader: 'css-loader',
                        options: { sourceMap: true }
                    },
                    // A tool for transforming CSS with JavaScript
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    require('postcss-import')({
                                        plugins: [
                                        ],
                                        path: ['./node_modules'],
                                    }),
                                    require('tailwindcss'),
                                    require('postcss-preset-env')({
                                        autoprefixer: {},
                                        features: {
                                            'nesting-rules': true,

                                            // https://github.com/tailwindlabs/tailwindcss/issues/1190
                                            // BUG: ... from Css Minimizer. Expected an opening square bracket.
                                            'focus-within-pseudo-class': false,
                                        }
                                    }),
                                ]
                            },
                            sourceMap: true
                        }
                    },
                    // A webpack loader that rewrites relative paths in url()
                    // statements based on the original source file.
                    {
                        loader: 'resolve-url-loader',
                        options: { sourceMap: true }
                    },
                    // Compiles Sass to CSS
                    {
                        loader: 'sass-loader',
                        options: { sourceMap: true }
                    },
                ],
            },
            {
                test: /fonts\/(.*)\.(woff(2)?|ttf|eot|svg)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'fonts/[name][ext][query]'
                }
            },
            {
                test: /img\/(.*)\.(jp(e)?g|png|gif|svg)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'img/[name][ext][query]'
                }
            }
        ],
    },
    plugins: [
        /**
         * Remove .js files of sass entrypoint.
         */
        new RemoveEmptyScriptsPlugin(),
    ]
};
exports.jsModern = {
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                ['@babel/preset-env', {
                                    modules: false,
                                    useBuiltIns: 'entry',
                                    corejs: '3.12',
                                    targets: {
                                        browsers: [
                                            'Chrome >= 60',
                                            'Safari >= 10.1',
                                            'iOS >= 10.3',
                                            'Firefox >= 54',
                                            'Edge >= 15',
                                        ],
                                    },
                                }]
                            ],
                            cacheDirectory: true,
                        }
                    }
                ],
            },
        ]
    },
    target: ['web', 'es6'],
    plugins: [
        /**
         * A Webpack plugin for generating an asset manifest.
         */
        new WebpackManifestPlugin(),
    ],
};
exports.jsLegacy = {
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                ['@babel/preset-env', {
                                    modules: false,
                                    useBuiltIns: 'entry',
                                    corejs: '3.12',
                                    targets: {
                                        browsers: [
                                            '> 1%',
                                            'last 2 versions',
                                            'Firefox ESR',
                                        ],
                                    },
                                }]
                            ],
                            cacheDirectory: true,
                        }
                    }
                ],
            },
        ]
    },
    target: ['web', 'es5'],
    plugins: [
        /**
         * A Webpack plugin for generating an asset manifest.
         */
        new WebpackManifestPlugin({
            fileName: 'manifest-legacy.json',
        }),
    ],
};

webpack.dev.js

const { merge } = require('webpack-merge');
const { common, jsLegacy, jsModern } = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackBar = require('webpackbar');

const dev = merge(common, {
    mode: 'development',
    devtool: 'inline-source-map',
    plugins: [
        /**
         * This plugin extracts CSS into separate files. It creates a CSS file per
         * JS file which contains CSS. It supports On-Demand-Loading of CSS and
         * SourceMaps.
         */
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),

        new WebpackBar({}),
    ]
});

module.exports = [
    merge(dev, jsModern, {
        name: 'modern',
        output: {
            filename: '[name].js',
        },
    }),
    merge(dev, jsLegacy, {
        name: 'legacy',
        output: {
            filename: '[name].es5.js',
        },
    })
];
module.exports.parallelism = 1;

有人知道如何实现吗?还是不可能?

0 个答案:

没有答案