2017-06-13 2 views
2

Anfänger Vuejs Frage hier. Ich versuche sass Dateien mit Vuejs und Webpack zu kompilieren. Nach the instructions ich installierte:Wie man externe Sass-Verzeichnis mit Vuejs + Webpack einbinden?

npm install sass-loader node-sass --save-dev 

und dann kann ich sass Verarbeitung in meinen Komponenten verwenden:

<style lang="sass"> 
    /* This works with my local components */ 
</style> 

Das Problem ist, wenn ich sass Dateien in 3rd-Party-Module in node_modules lebenden definiert verwenden mag. Insbesondere möchte ich Material Components Web verwenden. Nun, wenn ich will sass Dateien in einer Komponente importieren:

<style lang="scss" scoped> 
    @import '@material/card/mdc-card'; 
</style> 

der folgende Fehler tritt auf:

Module build failed: 
    @import '@material/card/mdc-card'; 
    File to import not found or unreadable: @material/card/mdc-card. 

Die Frage

Wie kann ich den Ordner node_modules/@material im sass enthalten Prozessorkonfiguration?

webpack.base.conf.js

var path = require('path') 
var utils = require('./utils') 
var config = require('../config') 
var vueLoaderConfig = require('./vue-loader.conf') 

function resolve(dir) { 
    return path.join(__dirname, '..', dir) 
} 

module.exports = { 
    entry: { 
     app: './src/main.js' 
    }, 
    output: { 
     path: config.build.assetsRoot, 
     filename: '[name].js', 
     publicPath: process.env.NODE_ENV === 'production' 
      ? config.build.assetsPublicPath 
      : config.dev.assetsPublicPath 
    }, 
    resolve: { 
     extensions: ['.js', '.vue', '.json'], 
     alias: { 
      'vue$': 'vue/dist/vue.esm.js', 
      '@': resolve('src') 
     } 
    }, 
    module: { 
     rules: [ 
      { 
       test: /\.(js|vue)$/, 
       loader: 'eslint-loader', 
       enforce: 'pre', 
       include: [resolve('src'), resolve('test')], 
       options: { 
        formatter: require('eslint-friendly-formatter') 
       } 
      }, 
      { 
       test: /\.vue$/, 
       loader: 'vue-loader', 
       options: vueLoaderConfig 
      }, 
      { 
       test: /\.js$/, 
       loader: 'babel-loader', 
       include: [resolve('src'), resolve('test')] 
      }, 
      { 
       test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 
       loader: 'url-loader', 
       options: { 
        limit: 1000, 
        name: utils.assetsPath('img/[name].[hash:7].[ext]') 
       } 
      }, 
      { 
       test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 
       loader: 'url-loader', 
       options: { 
        limit: 10000, 
        name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 
       } 
      }, 
      { 
       test: /\.s[a|c]ss$/, 
       loader: 'style!css!sass', 

       /* ADDED THIS LINE, BUT NOT LUCK */ 
       options: { 
        includePaths: [resolve('node_modules')], 
       }, 

       /* THIS DON'T WORK EITHER */ 
       include: [resolve('node_modules')], 

      } 
     ] 
    } 
} 

vue-loader.conf.js

var utils = require('./utils') 
var config = require('../config') 
var isProduction = process.env.NODE_ENV === 'production' 

module.exports = { 
    loaders: utils.cssLoaders({ 
    sourceMap: isProduction 
     ? config.build.productionSourceMap 
     : config.dev.cssSourceMap, 
    extract: isProduction 
    }) 
} 

utils.js

var path = require('path') 
var config = require('../config') 
var ExtractTextPlugin = require('extract-text-webpack-plugin') 

exports.assetsPath = function (_path) { 
    var assetsSubDirectory = process.env.NODE_ENV === 'production' 
    ? config.build.assetsSubDirectory 
    : config.dev.assetsSubDirectory 
    return path.posix.join(assetsSubDirectory, _path) 
} 

exports.cssLoaders = function (options) { 
    options = options || {} 

    var cssLoader = { 
    loader: 'css-loader', 
    options: { 
     minimize: process.env.NODE_ENV === 'production', 
     sourceMap: options.sourceMap 
    } 
    } 

    // generate loader string to be used with extract text plugin 
    function generateLoaders (loader, loaderOptions) { 
    var loaders = [cssLoader] 
    if (loader) { 
     loaders.push({ 
     loader: loader + '-loader', 
     options: Object.assign({}, loaderOptions, { 
      sourceMap: options.sourceMap 
     }) 
     }) 
    } 

    // Extract CSS when that option is specified 
    // (which is the case during production build) 
    if (options.extract) { 
     return ExtractTextPlugin.extract({ 
     use: loaders, 
     fallback: 'vue-style-loader' 
     }) 
    } else { 
     return ['vue-style-loader'].concat(loaders) 
    } 
    } 

    // https://vue-loader.vuejs.org/en/configurations/extract-css.html 
    return { 
    css: generateLoaders(), 
    postcss: generateLoaders(), 
    less: generateLoaders('less'), 
    sass: generateLoaders('sass', { indentedSyntax: true }), 
    scss: generateLoaders('sass'), 
    stylus: generateLoaders('stylus'), 
    styl: generateLoaders('stylus') 
    } 
} 

// Generate loaders for standalone style files (outside of .vue) 
exports.styleLoaders = function (options) { 
    var output = [] 
    var loaders = exports.cssLoaders(options) 
    for (var extension in loaders) { 
    var loader = loaders[extension] 
    output.push({ 
     test: new RegExp('\\.' + extension + '$'), 
     use: loader 
    }) 
    } 
    return output 
} 
+0

Bitte geben Sie Ihre 'vueLoaderConfig' –

Antwort

2

sagen webpack/sasss-Loader, der ein @import Pfad als node_module aufgelöst werden sollte, anstatt eine lokale Datei, müssen Sie eine Tilde voranstellen:

@import '[email protected]/card/mdc-card'; 

So hat dies nichts zu tun mit vue-loader aber ist eine allgemeine sass-loader-pitfall.

Edit:

HINWEIS: Die Komponenten Sass-Dateien erwarten, dass das node_modules Verzeichnis der @Material Umfang Ordner mit auf dem Sass vorliegt Pfad enthalten, wie in der Dokumentation für diese CSS-lib zur Kenntnis genommen.

So müssen wir die inlcudePaths für Sass-.loader/node-Sass hinzufügen:

return { 
    css: generateLoaders(), 
    postcss: generateLoaders(), 
    less: generateLoaders('less'), 
    sass: generateLoaders('sass', { indentedSyntax: true, includePaths: [path.resolve(__dirname, '../node_modules'] }), 
    scss: generateLoaders('sass' { includePaths: [path.resolve(__dirname, '../node_modules'] }), 
    stylus: generateLoaders('stylus'), 
    styl: generateLoaders('stylus') 
} 
+0

Danke für die Antwort. Das Problem ist, dass in '@ material/card/mdc-card' weitere Importe wie' import @ material/mixins' enthalten sind. Diese Importe haben nicht die '~', also funktioniert das nicht. – Cartucho

+0

siehe meine Bearbeitung. –

+0

Großartig! Vielen Dank für Ihre Zeit, dies zu überprüfen. – Cartucho

0

Bitte benutzen Sie Installieren Sie die einzelnen Komponenten?

npm install --save @material/button @material/card @material/textfield @material/typography 
+0

Nein, ich installiert das ganze Paket:' npm installieren --save Material-Komponenten-Web' – Cartucho

+0

Ich denke, Sie müssen den Root-Pfad definieren. Verwenden Sie den absoluten Pfad, um sicherzustellen, dass das Verzeichnis richtig ist. Überprüfen Sie dies: https://webpack.github.io/docs/configuration.html#resolve-root –

+0

Hallo Pedro, danke für die Antwort. Ich benutze den absoluten Pfad (mit der Funktion 'resolve' definiert in' webpack.base.conf.js'.Ich schreibe auch den absoluten Pfad explizit, aber es funktioniert nicht. Ich weiß wirklich nicht, wie ich das lösen soll. – Cartucho

Verwandte Themen