2017-06-13 53 views
2

初学者Vuejs问题在这里。我试图用Vuejs和Webpack编译sass文件。继the instructions我装:如何在Vuejs + Webpack中包含外部sass目录?

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

,然后,我可以在我的组件使用SASS处理:

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

问题是,当我想用​​在生活中node_modules第三方模块定义sass文件。特别是我想用Material Components Web。现在,当我要导入一个组件SASS文件:

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

以下错误发生:

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

问题

我怎么能包括文件夹node_modules/@material在SASS处理器配置?

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

请提供您的'vueLoaderConfig' –

回答

2

告诉的WebPack/sasss装载机,一个@import路径应被解析为一个node_module,而不是一个本地文件,你必须在前面加上一个波浪线:

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

所以这无关用vue-loader但是是一般的sass-loader-陷阱。

编辑:如在该文档中该CSS的lib指出:

注:组件的萨斯文件期望含有@material范围文件夹中的node_modules目录存在于萨斯包括路径。

所以我们要增加对SASS-.loader /节点青菜的inlcudePaths:

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

感谢您的回复。问题是在'@ material/card/mdc-card'里面有其他的输入,例如'import @ material/mixins'。那些进口没有'〜',所以这不起作用。 – Cartucho

+0

请参阅我的编辑。 –

+0

太棒了!感谢您的时间审查这一点。 – Cartucho

0

你有没有安装各个组件?

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

没有,我装全包:'NPM安装--save material-components-web' – Cartucho

+0

我想你需要定义根路径。使用绝对路径来确保目录是正确的。 选中此:https://webpack.github.io/docs/configuration.html#resolve-root –

+0

嗨佩德罗,感谢您的答复。我使用绝对路径(在'webpack.base.conf.js'中定义了函数'resolve')。我也明确写出绝对路径,但它不起作用。我真的不知道如何解决这个问题。 – Cartucho

相关问题