无法使用 Webpack 3 正确加载 sass 和 font-awesome

Posted

技术标签:

【中文标题】无法使用 Webpack 3 正确加载 sass 和 font-awesome【英文标题】:Cannot load sass and font-awesome properly with Webpack 3 【发布时间】:2018-09-23 00:38:45 【问题描述】:

目前,我正在尝试使用 Webpack3 加载我的 scss 文件和 font-awesome。

这是我的 webpack.config.js

const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const precss = require('precss');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = 
    entry: [
        './Scripts/app.ts',
        './Scripts/scss/main.scss',
        //'font-awesome/scss/font-awesome.scss',
        'tether'
    ],
    output: 
        filename: 'bundle.js',
        path: path.resolve(__dirname, './Scripts/dist')
    ,
    module: 
        rules: [
            
                loader: 'ts-loader',
                test: /\.ts$/,
                exclude: /node_modules/
            ,
            
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
            ,
            
                test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                use: 'url-loader?limit=10000'
            ,
            
                test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
                use: 'file-loader'
            ,
            
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    'file-loader?name=images/[name].[ext]',
                    'image-webpack-loader?bypassOnDebug'
                ]
            ,
            // font-awesome
            
                test: /font-awesome\.config\.js/,
                use: [
                     loader: 'style-loader' ,
                     loader: 'font-awesome-loader' 
                ]
            ,
            // Bootstrap 4
            
                test: /bootstrap\/dist\/js\/umd\//,
                use: 'imports-loader?jQuery=jquery'
            ,
            // SCSS pre-processing
            
                test: /\.(scss)$/,
                //use: ExtractTextPlugin.extract(
                //    fallback: 'style-loader',
                //    use: [
                //        // the order of the loaders cannot be changed
                //        
                //            loader: 'css-loader',
                //            options:  minimize: false  // minifize css file
                //        , // translates CSS into CommonJS modules
                //        
                //            loader: 'postcss-loader', // Run post css actions
                //            options: 
                //                // post css plugins, can be exported to postcss.config.js
                //                plugins() 
                //                    return [precss, autoprefixer];
                //                
                //            
                //        ,
                //         loader: 'sass-loader'  // compiles SASS to CSS
                //    ]
                //)

                use: [
                    loader: 'style-loader' // creates style nodes from JS strings
                , 
                    loader: 'css-loader' // translates CSS into CommonJS
                , 
                    loader: 'sass-loader' // compiles Sass to CSS
                ]
            
        ]
    ,
    resolve: 
        extensions: ['.ts', '.js']
    ,
    plugins: [
        new ExtractTextPlugin('main.css', 
            allChunks: true
        ),
        // minify the bundled js files
        new webpack.optimize.UglifyJsPlugin(
            include: /\.js$/,
            minimize: true,
            sourceMap: true
        ),
        new webpack.ProvidePlugin(
            jQuery: 'jquery',
            jquery: 'jquery',
            $: 'jquery',
            tether: 'tether',
            Tether: 'tether',
            Popper: ['popper.js', 'default'],
            Alert: 'exports-loader?Alert!bootstrap/js/dist/alert',
            Button: 'exports-loader?Button!bootstrap/js/dist/button',
            Carousel: 'exports-loader?Carousel!bootstrap/js/dist/carousel',
            Collapse: 'exports-loader?Collapse!bootstrap/js/dist/collapse',
            Dropdown: 'exports-loader?Dropdown!bootstrap/js/dist/dropdown',
            Modal: 'exports-loader?Modal!bootstrap/js/dist/modal',
            Popover: 'exports-loader?Popover!bootstrap/js/dist/popover',
            Scrollspy: 'exports-loader?Scrollspy!bootstrap/js/dist/scrollspy',
            Tab: 'exports-loader?Tab!bootstrap/js/dist/tab',
            Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
            Util: 'exports-loader?Util!bootstrap/js/dist/util'
        )
    ],
    devtool: 'source-map'
;

更多细节(基于 .scss 的规则):

    我在 main.scss 中导入了 font-awesome scss,使用:
$fa-font-path: "~/node_modules/font-awesome/fonts";
@import '~font-awesome/scss/font-awesome.scss';

    字体和图标引用“node_moduldes”中的包(这不是我在生产中想要的)

    构建工件只是 bundle.js

如果我运行 webpack,似乎一切正常。但是,一旦我们开始生产,我假设到 node_module 的图标/字体链接会被破坏。

这是我的 scss:

如果我使用注释掉的代码,font-awesome 可以正确加载,但我的scss 文件不能加载。

详情:

可以制作所有的svg/ttf/eot文件 scss 可以处理成 css 文件,但是当我加载页面时,它们看起来很糟糕。

我的问题:

有什么方法可以让我使用所有工件加载 font-awesome 并使用 Webpack 3 正确加载我的 scss 组件(如生产)?

提前致谢。

【问题讨论】:

我也遇到了同样的问题,由于找不到任何解决方案,我最终编写了一个 gulp 任务,将与字体相关的文件移动到目标文件夹以提供给客户端。 谢谢@DeepakKumar 这可能是一个临时解决方案。但是,我不想在我们的构建管道中引入另一个工具。如果我们能用 webpack 处理好就好了。 【参考方案1】:

我花了一些时间努力寻找更好的解决方案。这是我的方法,它按预期工作:

我参考了两个资源:

    Using FontAwesome with Sass sass 加载器:https://github.com/webpack-contrib/sass-loader

我想强调几件事:

我们如何“导入”包。我将导入 css 文件从我的 TypeScript 文件移动到 main.scss。一切都像魅力一样。 另一个重要的事情是 sass-loader 有 @import 规则

webpack 提供了一种高级机制来解析文件。这 sass-loader 使用 node-sass 的自定义导入器功能来传递所有 对 webpack 解析引擎的查询。因此你可以导入你的 Sass 来自 node_modules 的模块。只需在它们前面加上一个 ~ 来告诉 webpack 这不是相对导入:

@import "~bootstrap/dist/css/bootstrap";

只在前面加上 ~ 很重要,因为 ~/ 解析为 主目录。 webpack 需要区分 bootstrap 和 ~bootstrap 因为 CSS 和 Sass 文件没有特殊的语法 导入相关文件。编写 @import "file" 与 @import "./file";

来自https://github.com/webpack-contrib/sass-loader

这是我的 main.scss 文件:

@import '~bootstrap/dist/css/bootstrap.min.css';
@import '~inputmask/css/inputmask.css';

$fa-font-path: "~font-awesome/fonts";
@import '~font-awesome/scss/font-awesome.scss';

// import partials
@import "variables";
@import "mixins";

@import "accordion";
@import "buttons";
@import "cards";
@import "container";
@import "errors";
@import "fonts";
@import "form";
@import "headers";
@import "hyperlinks";
@import "tables";
@import "warnings";
@import "wcb-footer";
@import "wcb-header";

@import "asmt-report"; // optional

【讨论】:

以上是关于无法使用 Webpack 3 正确加载 sass 和 font-awesome的主要内容,如果未能解决你的问题,请参考以下文章

Sass 加载器无法使用 Encore webpack 和 Symfony 5 加载 url

Webpack sass 加载器无法识别全局变量文件

Webpack 中 CSS / SASS 的加载器

Webpack SASS 加载器无法对常见的 SCSS 导入进行重复数据删除

使用 webpack 2 和 vue-cli 加载本地字体

webpack 3 sass-loader 无法导入没有相对路径的 scss 文件