7

Tôi có cấu hình sau Webpack (xấp xỉ, nó đã được đơn giản hóa cho bài này):Không thể giải quyết url tuyệt đối() đường dẫn cho hình ảnh nền trong CSS với Webpack

const rootPublic = path.resolve('./public'); 
const LOCAL_IDENT_NAME = 'localIdentName=[name]_[local]_[hash:base64:5]'; 
const CSS_LOADER = `css?sourceMap&${LOCAL_IDENT_NAME}&root=${rootPublic}`; 
const SASS_LOADER = 'sass?sourceMap&includePaths[]=' + path.resolve(__dirname, './src/styles'); 

// ... loaders: 

loaders: [ 
    { 
    test: /\.(jpe?g|png|gif|svg)$/, 
    loader: 'url-loader?limit=10000&name=[path][name].[ext]' 
    }, 
    { 
    test: /\.scss$/, 
    loader: config.DEVELOPMENT_MODE ? `style!${CSS_LOADER}!autoprefixer!${SASS_LOADER}` 
       : ExtractTextPlugin.extract('style', `${CSS_LOADER}!autoprefixer!${SASS_LOADER}`) 
    }, // ... 
] 

Bây giờ này hoạt động hoàn toàn tốt đẹp cho hình ảnh tham chiếu thông thường trong các tập tin SCSS:

.some-static-class { 
    background: url('/images/bg.png'); 
} 

Tuy nhiên, nó không công việc khi sử dụng :local chỉ:

:local .SomeClass { 
    background: url('/images/bg.png'); 
} 

Và tôi nghĩ đó là vì root được xác định cho trình tải CSS. Tôi gặp phải lỗi xây dựng: Module not found: Error: Cannot resolve 'file' or 'directory' ./../../../../../../../../images/bg.gif

Nếu thay vào đó, tôi xóa root từ cấu hình css-loader, thì nó sẽ ổn nhưng sau đó bạn thực sự mở liên kết trong tab mới , nó trỏ đến: chrome-devtools://devtools/bundled/"/images/bg.png" mà rõ ràng là không giải quyết chính xác.

Tôi không chắc chắn nếu sự cố xảy ra với cấu hình url-loader hoặc những gì đang xảy ra chính xác.

Tôi đã phát xung quanh với các cấu hình webpack khác nhau để chỉ định resolve.root, resolve.modulesDirectories, v.v. nhưng hoàn toàn không chắc chắn nếu chúng có bất kỳ ảnh hưởng nào hoặc nếu tôi chỉ hoàn toàn sai. Tôi cũng đã xem qua resolve-url-loader nhưng không chắc chắn đó có phải là điều tôi cần chút nào hay không.

Bất kỳ ý tưởng nào? MTIA!

CẬP NHẬT

tôi nên lưu ý rằng nó hoạt động tốt trong Safari, nhưng không phải trong Chrome. Vì vậy, nó có vẻ giống như một lỗi cụ thể của Chrome, nhưng nó không thực tế để làm tất cả phát triển của chúng tôi trong Safari.

Tôi cũng đã xem qua, vue-style-loader, là một nhánh của trình tải kiểu có xác nhận khắc phục sự cố này, nhưng cách khắc phục sự cố đó là dựa vào phương pháp thoát/không sử dụng hacky.

Trả lời

5

Một giải pháp khả thi mà tôi có thể đưa ra được những điều sau đây:

Sử dụng resolve-url-loader (ngay sau khi sass-loader):

style!${CSS_LOADER}!autoprefixer!resolve-url!${SASS_LOADER} 

Sau đó, xác định một resolve.alias cho hình ảnh tĩnh:

resolve: { 
    alias: { 
    images: path.join(__dirname, 'public/images') 
    } 
} 

Và sau đó trong CSS, bạn có thể trỏ đến hình ảnh như vậy:

:local .SomeClass { 
    background: url('images/bg.png'); 
} 

Tùy thuộc vào cấu trúc URL của bạn, bạn cũng có thể cần phải tinh chỉnh các url-loader tên param:

{ 
    test: /\.(jpe?g|png|gif|svg)$/, 
    loader: 'url-loader?limit=10000&name=images/[name].[ext]' 
} 

Vì vậy, tôi không biết nếu có một cách sạch hơn để giải quyết vấn đề này, nhưng đó là điều tốt nhất tôi có thể đưa ra cho đến nay. Tôi muốn chào đón bất kỳ phản hồi hoặc lựa chọn thay thế nào.

Cảm ơn!

CẬP NHẬT 6/30/2016

Có một vài PR của ra rằng sẽ giải quyết vấn đề này, nhưng nhà duy trì thích giải pháp cho được trong AST CSS chứ không phải là trong bộ nạp CSS ...

https://github.com/webpack/style-loader/pull/124 https://github.com/webpack/style-loader/pull/96

đây là hy vọng một sửa chữa thực xảy ra sớm ...

1

Với webpack 2:

Trong tệp .scss của bạn, hãy sử dụng ~ trước đường dẫn.

.yourClass { 
     background: url('~img/wallpaper.png'); 
} 

tận dụng các gốc quyết tâm từ webpack, thêm video này vào webpack.config.js của bạn:

resolve: { 
     modules: [ 
      path.resolve(root), 
      'node_modules' 
     ] 
    }, 

Nó sẽ làm việc cũng cho @import, ví dụ như @import "~ otherfile.scss "

+0

Điều này đã cứu mạng tôi, cảm ơn bạn! – cinnaroll45

+0

@ cinnaroll45 chúc mừng! :) – Sergiu

Các vấn đề liên quan