【问题标题】:Webpack sass loader resolve absolute pathWebpack sass 加载器解析绝对路径
【发布时间】:2018-12-27 16:43:41
【问题描述】:

我希望能够在@import 语句中使用绝对路径。比如:

@import '/templates/common/variables'

但是,sass 似乎将其解析为我的文件系统中的绝对 URL。我希望它在我的项目文件夹中查找。例如。我的文件实际上位于/home/username/project/templates/common/_variables.scss

这有可能吗?

我已经看过 includePaths 但这似乎什么也没做。

我正在使用 encore 来编写我的 webpack 文件,它看起来大致是这样的:

const Encore = require('@symfony/webpack-encore');
Encore
    .setOutputPath("web/build/")
    .setPublicPath("/build")
    // [...]
    .enableSassLoader(options => {
        options.includePaths = [path.resolve(__dirname, '/web')];
    })
;

这里也是生成的 webpack 配置(很长,我没有用上面的示例路径替换我的真实路径):

{  
    context:'/var/www',
    entry:{  
        index:[  
            './polyfills.js',
            './web/typo3conf/ext/hn_project/ext_index.js',
            './web/typo3conf/ext/hn_templates/ext_index.js'
        ],
        backend:[  
            './polyfills.js',
            './web/typo3conf/ext/hn_project/ext_backend.js'
        ]
    },
    output:{  
        path:'/var/www/web/build',
        filename:'[name].[chunkhash:8].js',
        publicPath:'/build/',
        pathinfo:false
    },
    module:{  
        rules:[  
            {  
                test:/\.jsx?$/,
                exclude:/(node_modules|bower_components)/,
                use:[  
                    {  
                        loader:'babel-loader',
                        options:{  
                            cacheDirectory:true,
                            presets:[  
                                [  
                                    'env',
                                    {  
                                        modules:false,
                                        targets:{  
                                            browsers:[  
                                                'and_chr 67',
                                                'and_uc 11.8',
                                                'chrome 67',
                                                'chrome 66',
                                                'chrome 65',
                                                'edge 17',
                                                'edge 16',
                                                'firefox 60',
                                                'firefox 59',
                                                'firefox 52',
                                                'ie 11',
                                                'ie 10',
                                                'ie_mob 11',
                                                'ie_mob 10',
                                                'ios_saf 11.3',
                                                'ios_saf 11.0-11.2',
                                                'opera 53',
                                                'opera 52',
                                                'safari 11.1',
                                                'safari 11',
                                                'samsung 6.2'
                                            ],
                                            uglify:true
                                        },
                                        useBuiltIns:true
                                    }
                                ]
                            ],
                            plugins:[  

                            ]
                        }
                    }
                ]
            },
            {  
                test:/\.css$/,
                use:[  
                    {  
                        loader:'/var/www/node_modules/extract-text-webpack-plugin/dist/loader.js',
                        options:{  
                            omit:1,
                            remove:true
                        }
                    },
                    {  
                        loader:'style-loader'
                    },
                    {  
                        loader:'css-loader',
                        options:{  
                            minimize:true,
                            sourceMap:false,
                            importLoaders:1
                        }
                    },
                    {  
                        loader:'postcss-loader',
                        options:{  
                            sourceMap:false,
                            ident:'postcss',
                            plugins:[  
                                {  
                                    [  
                                        Function:plugin
                                    ]                                    options:{  
                                        grid:false
                                    },
                                    browsers:undefined,
                                    info:[  
                                        Function
                                    ],
                                    postcssPlugin:'autoprefixer',
                                    postcssVersion:'6.0.23'
                                }
                            ]
                        }
                    }
                ]
            },
            {  
                test:/\.(png|jpg|jpeg|gif|ico|svg|webp)$/,
                loader:'url-loader',
                options:{  
                    name:'images/[name].[hash:8].[ext]',
                    publicPath:'/build/',
                    limit:4096
                }
            },
            {  
                test:/\.(woff|woff2|ttf|eot|otf)$/,
                loader:'url-loader',
                options:{  
                    name:'fonts/[name].[hash:8].[ext]',
                    publicPath:'/build/',
                    limit:4096
                }
            },
            {  
                test:/\.s[ac]ss$/,
                use:[  
                    {  
                        loader:'/var/www/node_modules/extract-text-webpack-plugin/dist/loader.js',
                        options:{  
                            omit:1,
                            remove:true
                        }
                    },
                    {  
                        loader:'style-loader'
                    },
                    {  
                        loader:'css-loader',
                        options:{  
                            minimize:true,
                            sourceMap:false,
                            importLoaders:1
                        }
                    },
                    {  
                        loader:'postcss-loader',
                        options:{  
                            sourceMap:false,
                            ident:'postcss',
                            plugins:[  
                                {  
                                    [  
                                        Function:plugin
                                    ]                                    options:{  
                                        grid:false
                                    },
                                    browsers:undefined,
                                    info:[  
                                        Function
                                    ],
                                    postcssPlugin:'autoprefixer',
                                    postcssVersion:'6.0.23'
                                }
                            ]
                        }
                    },
                    {  
                        loader:'resolve-url-loader',
                        options:{  
                            sourceMap:false
                        }
                    },
                    {  
                        loader:'sass-loader',
                        options:{  
                            sourceMap:true,
                            includePaths:[  
                                '/web'
                            ]
                        }
                    }
                ]
            }
        ]
    },
    plugins:[  
        ExtractTextPlugin        {  
            filename:'[name].[contenthash:8].css',
            id:1,
            options:{  
                allChunks:false
            }
        },
        DeleteUnusedEntriesJSPlugin        {  
            entriesToDelete:[  

            ]
        },
        ManifestPlugin        {  
            opts:{  
                publicPath:null,
                basePath:'build/',
                fileName:'manifest.json',
                transformExtensions:/^(gz|map)$/i,
                writeToFileEmit:true,
                seed:null,
                filter:null,
                map:null,
                generate:null,
                sort:null,
                serialize:[  
                    Function:serialize
                ]
            }
        },
        LoaderOptionsPlugin        {  
            options:{  
                debug:false,
                options:{  
                    context:'/var/www',
                    output:{  
                        path:'/var/www/web/build'
                    }
                },
                test:{  
                    test:[  
                        Function:test
                    ]
                }
            }
        },
        HashedModuleIdsPlugin        {  
            options:{  
                hashFunction:'md5',
                hashDigest:'base64',
                hashDigestLength:4
            }
        },
        WebpackChunkHash        {  
            algorithm:'md5',
            digest:'hex',
            additionalHashContent:[  
                Function
            ]
        },
        ProvidePlugin        {  
            definitions:{  
                '$':'jquery',
                jQuery:'jquery',
                'window.jQuery':'jquery'
            }
        },
        CleanWebpackPlugin        {  
            paths:[  
                '**/*'
            ],
            options:{  
                root:'/var/www/web/build',
                verbose:false,
                allowExternal:false,
                dry:false
            }
        },
        DefinePlugin        {  
            definitions:{  
                'process.env':{  
                    NODE_ENV:'"production"'
                }
            }
        },
        UglifyJsPlugin        {  
            options:{  
                sourceMap:false
            }
        },
        FriendlyErrorsWebpackPlugin        {  
            compilationSuccessInfo:{  
                messages:[  

                ]
            },
            onErrors:undefined,
            shouldClearConsole:false,
            formatters:[  
                [  
                    Function:format
                ],
                [  
                    Function:format
                ],
                [  
                    Function:format
                ],
                [  
                    Function:format
                ],
                [  
                    Function:format
                ],
                [  
                    Function:format
                ]
            ],
            transformers:[  
                [  
                    Function:transform
                ],
                [  
                    Function:transform
                ],
                [  
                    Function:transform
                ],
                [  
                    Function:transform
                ],
                [  
                    Function:transform
                ],
                [  
                    Function:transform
                ]
            ]
        },
        AssetOutputDisplayPlugin        {  
            outputPath:'web/build',
            friendlyErrorsPlugin:FriendlyErrorsWebpackPlugin            {  
                compilationSuccessInfo:{  
                    messages:[  

                    ]
                },
                onErrors:undefined,
                shouldClearConsole:false,
                formatters:[  
                    [  
                        Function:format
                    ],
                    [  
                        Function:format
                    ],
                    [  
                        Function:format
                    ],
                    [  
                        Function:format
                    ],
                    [  
                        Function:format
                    ],
                    [  
                        Function:format
                    ]
                ],
                transformers:[  
                    [  
                        Function:transform
                    ],
                    [  
                        Function:transform
                    ],
                    [  
                        Function:transform
                    ],
                    [  
                        Function:transform
                    ],
                    [  
                        Function:transform
                    ],
                    [  
                        Function:transform
                    ]
                ]
            }
        },
        {  
            apply:[  
                Function:bound apply
            ]
        },
        ZopfliPlugin        {  
            asset:'[path].gz[query]',
            algorithm:[  
                Function
            ],
            filename:false,
            compressionOptions:{  
                verbose:false,
                verbose_more:false,
                numiterations:15,
                blocksplitting:true,
                blocksplittinglast:false,
                blocksplittingmax:15
            },
            test:/\.(js|css|svg|ttf)$/,
            threshold:1400,
            minRatio:0.8,
            deleteOriginalAssets:false
        },
        BrotliPlugin        {  
            asset:'[path].br[query]',
            test:/\.(js|css|svg|ttf)$/,
            threshold:1400,
            minRatio:0.8,
            deleteOriginalAssets:false,
            compress:[  
                Function
            ]
        }
    ],
    performance:{  
        hints:false
    },
    stats:{  
        hash:false,
        version:false,
        timings:false,
        assets:false,
        chunks:false,
        maxModules:0,
        modules:false,
        reasons:false,
        children:false,
        source:false,
        errors:false,
        errorDetails:false,
        warnings:false,
        publicPath:false
    },
    resolve:{  
        extensions:[  
            '.js',
            '.jsx',
            '.vue',
            '.ts',
            '.tsx'
        ],
        alias:{  

        }
    },
    externals:{  

    }
}

这里还有一些可能有趣的软件包版本

@symfony/webpack-encore@0.20.1
node-sass@4.9.0
sass-loader@7.0.3
webpack@3.12.0

【问题讨论】:

    标签: webpack sass sass-loader webpack-encore


    【解决方案1】:

    您可以使用 Webpack 别名。将每次导入 /templates 解析到项目的 templates/ 文件夹。

    const path = require('path');
    
    module.exports = {
      // ...
      resolve: {
        alias: {
          '/templates': path.resolve(__dirname, './templates')
        }
      }
    };
    

    我阅读了@sympony/webpack-encore 并找到了addAliases 设置。您可以使用以下示例。

    const path = require('path');
    const Encore = require('@symfony/webpack-encore');
    
    Encore
      // ...
      .addAliases({
        '/templates': path.resolve(__dirname, './templates')
      });
    

    在您的 Scss/SASS 中导入使用 ~ 前面的文件路径。

    @import '~/templates/common/variables'
    

    【讨论】:

    • 这在 scss/sass 中不起作用。它确实可以在 js 导入中使用,但这很好。
    • Webpack 可以解析其他文件导入。 github.com/webpack-contrib/sass-loader#imports
    • 您只需要更改您的导入,在导入路径前添加~。喜欢@import '~/templates/... .scss'。我会用它更新我的答案
    • ~/ 解析到主目录,但简单的 ~templates 就可以了!谢谢:)
    【解决方案2】:

    可能您自己已经找到了答案,但以防万一其他人在这里使用 url() 的常见方法是使用 resolve-url-loader。另请注意,您必须在前面的加载器中将 sourceMap 设置为 true。

    https://www.npmjs.com/package/resolve-url-loader

    这是一个如何使用它的例子:

    {
        // Note that sourceMap is needed to be true at least in sass-loader so resolve-url-loader works fine
        test: /\.scss$/,
        use: [
            {
                loader: "style-loader",
                options: { sourceMap: true }
            }, // Adds CSS to the DOM by injecting a <style> tag
            {
                loader: "css-loader",
                options: { sourceMap: true }
            }, // The css-loader interprets @import and url() like import/require() and will resolve them.
            {
                loader: "postcss-loader",
                options: {
                    sourceMap: true,
                    plugins: [
                        require("autoprefixer")({ browsers: ["last 2 versions"] })
                    ]
                }
            }, // Adds prefix for cross-browser support
            {
                loader: "resolve-url-loader",
                options: { sourceMap: true }
            }, // Webpack loader that resolves relative paths in url() statements based on the original source file.
            {
                loader: "sass-loader",
                options: { sourceMap: true }
            } // Loads a Sass/SCSS file and compiles it to CSS.
        ]
    }
    

    【讨论】:

    • 你在谈论一个不同的问题。 Sass 在其自身中导入其他 sass 文件,因此此时 resolve-url-loader 为时已晚。而且我还没有找到解决这个问题的方法。 Less 有一个paths 选项。似乎 includePaths 是我正在寻找的,但它不起作用。在这一点上我有点接受它。
    【解决方案3】:

    我已成功使用绝对导入,在 .env 中设置了 ~ 和 NODE_ENV

    /.env:

    NODE_PATH=src/
    

    假设 /src/styles/variables.scss 存在于任何 .scss 文件中:

    @import ~styles/variables`
    

    适用于 CreateReactApp v2.0。

    参考:https://github.com/facebook/create-react-app/issues/4494#issuecomment-412113793

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 2017-12-15
      • 2018-12-28
      • 2022-07-05
      • 2023-04-08
      • 2010-10-03
      相关资源
      最近更新 更多