Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用rails/webpacker在vue应用程序中使用vuetify自定义sass变量_Javascript_Ruby On Rails_Webpack_Vuetify.js_Webpacker - Fatal编程技术网

Javascript 使用rails/webpacker在vue应用程序中使用vuetify自定义sass变量

Javascript 使用rails/webpacker在vue应用程序中使用vuetify自定义sass变量,javascript,ruby-on-rails,webpack,vuetify.js,webpacker,Javascript,Ruby On Rails,Webpack,Vuetify.js,Webpacker,我正在使用Rails后端开发Vue应用程序。我正在使用Vuetify,我想自定义SCSS变量。遗憾的是,我无法使用Vue CLI,因为我们正在将所有内容与webpack捆绑在一起,webpack是用于webpack的rails实现。因此,我尝试使用基本webpack配置选项来实现它 我还不能直接做到这一点,因为webpacker有自己的css/sass/scss加载程序配置。但是,我可以挂接到现有的加载程序中,并在稍后设置它们的函数中修改选项: // config/webpack/environ

我正在使用Rails后端开发Vue应用程序。我正在使用Vuetify,我想自定义SCSS变量。遗憾的是,我无法使用Vue CLI,因为我们正在将所有内容与webpack捆绑在一起,webpack是用于webpack的rails实现。因此,我尝试使用基本webpack配置选项来实现它

我还不能直接做到这一点,因为webpacker有自己的css/sass/scss加载程序配置。但是,我可以挂接到现有的加载程序中,并在稍后设置它们的函数中修改选项:

// config/webpack/environment.js

const updateStyleLoaders = (arr) => {
  arr.forEach((item) => {
    const loader = environment.loaders.get(item);

    // Use vue-style-loader instead of default to parse Vue SFCs
    const styleConfig = loader.use.find((el) => el.loader === 'style-loader');
    if (styleConfig !== undefined) {
      styleConfig.loader = 'vue-style-loader';
    }

    // VUETIFY: Use Dart-Sass and Fibers for Sass loaders
    const sassConfig = loader.use.find((el) => el.loader === 'sass-loader');
    if (sassConfig !== undefined) {
      const opts = sassConfig.options;

      opts.implementation = require('sass'); // Use dart-sass instead of node-sass
      opts.fiber = require('fibers'); // improves compilation speed
      opts.data = "@import '@/assets/sass/variables.scss';"; // Import custom variables
    }
  });
};

// Call fuction for all css-related loaders
updateStyleLoaders(['sass', 'css', 'moduleCss', 'moduleSass']);


// @/assets/sass/variables.scss

$body-font-family: "Comic Sans MS", "Comic Sans", cursive; // just wanna have fun
$border-radius-root: 20px;

现在问题来了:

sass加载程序规则同时匹配“sass”和“scss”。在本文中,sass和scss的匹配是分开进行的。添加分号时,在编译过程中会出现以下错误:

./node_modules/vuetify/src/components/VAlert/VAlert.sass
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):

// Imports
                                     ^
      Semicolons aren't allowed in the indented syntax.
  ╷
1 │ @import '@/assets/sass/variables.scss';
  │                                       ^
  ╵
  stdin 1:39  root stylesheet
这告诉我该行实际上是由sass加载程序正确地添加到中添加的vuetify组件中的。但是,当我从import语句中删除分号以支持sass的缩进语法时,我看不到样式更改


在这种情况下,我将如何自定义vuetify组件?Webpacker使用sass loader v7.3.1。

大约两天前,我在尝试将Storybook配置为在Vue/Vuetify项目中工作时遇到了一个非常类似的问题。非常令人沮丧。下面是我现在工作的
webpack.config.js
文件的样子:

const path=require('path'))
module.exports=异步({config})=>{
config.module.rules.push({
测试:/\.s(a|c)ss$/,
使用:[
“样式加载器”,
“css加载程序”,
//“sass loader”
{
加载器:“sass加载器”,
选项:{
sassOptions:{
缩进语法:true,//{
arr.forEach((项目)=>{
const loader=environment.loaders.get(item);
//使用vue样式加载器而不是默认值来解析vue SFC
const styleConfig=loader.use.find((el)=>el.loader==='style loader');
if(styleConfig!==未定义){
styleConfig.loader='vue样式加载器';
}
//VUETIFY:对Sass装载机使用Dart Sass和光纤
const sassConfig=loader.use.find((el)=>el.loader=='sass-loader');
if(sassConfig!==未定义){
const opts=sassConfig.options;
opts.implementation=require('sass');//使用dart sass而不是节点sass
opts.fiber=require('fibers');//提高了编译速度
//添加这一行
opts.sassOptions.indentedSytax=true;
//或者是这个???
opts.indentedSyntax=true;
//然后删除分号(或者保留分号并将indentedSyntax设置为false?)
opts.data=“@import'@/assets/sass/variables.scss'”//导入自定义变量
}
});
};
.FWIW,我发现网页包配置是我面临的最具挑战性的事情之一。它肯定是在硬模式下进行编程!多亏了的帮助,我已经让它工作了

可以使用
environment.loaders.delete('sass')//删除默认加载程序。//与'moduleSass','moduleCss','css'相同。

然后,它们可以被新的替换。我已将SCS和sass加载程序分离到它们自己的文件中:

// config/webpack/loaders/sass.js
const { config } = require('@rails/webpacker');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  test: /\.sass$/,
  use: [
    config.extract_css === false
      ? 'vue-style-loader'
      : MiniCssExtractPlugin.loader,
    {
      loader: 'css-loader',
      options: {
        sourceMap: true,
        importLoaders: 2,
      },
    },
    {
      loader: 'sass-loader',
      options: {
        sourceMap: true,
        implementation: require('sass'),
        fiber: require('fibers'),
        data: '@import "app/frontend/src/assets/styles/variables.scss"',
      },
    },
  ],
};

// config/webpack/loaders/scss.js

const { config } = require('@rails/webpacker');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  test: /\.scss$/,
  use: [
    config.extract_css === false
      ? 'vue-style-loader'
      : MiniCssExtractPlugin.loader,
    {
      loader: 'css-loader',
      options: {
        sourceMap: true,
        importLoaders: 2,
      },
    },
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: true,
      },
    },
    {
      loader: 'sass-loader',
      options: {
        sourceMap: true,
        implementation: require('sass'),
        fiber: require('fibers'),
        data: '@import "app/frontend/src/assets/styles/variables.scss";',
      },
    },
  ],
};
这些重新实现了与CSS提取的基本webpacker集成

然后,我将它们添加到主配置中,如下所示:

// config/webpack/environment.js

const { environment } = require('@rails/webpacker');
const path = require('path');

// Plugins
const { VueLoaderPlugin } = require('vue-loader');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');

// Loaders
const erb = require('./loaders/erb');
const sass = require('./loaders/sass');
const scss = require('./loaders/scss');
const vue = require('./loaders/vue');
const yml = require('./loaders/yml');

// Remove webpacker's conflicting loaders
environment.loaders.delete('moduleSass');
environment.loaders.delete('moduleCss');
environment.loaders.delete('sass');

// Modify base css loader to support vue SFC style tags
environment.loaders.get('css').use.find((el) => el.loader === 'style-loader').loader = 'vue-style-loader';

// Apply plugins
environment.plugins.prepend('VuetifyLoaderPlugin', new VuetifyLoaderPlugin());
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin());

// Apply custom loaders
environment.loaders.append('erb', erb);
environment.loaders.append('yml', yml);
environment.loaders.append('vue', vue);
environment.loaders.append('sass', sass);
environment.loaders.append('scss', scss);

// Shorthands for import statements
environment.config.resolve.alias = {
  // Use the same vue package everywhere
  vue: 'vue/dist/vue.esm',
  // use '@' as absolute path from /src
  '@': path.resolve(__dirname, '../../app/frontend/src/'),
};

module.exports = environment;
这里还有一个重要的部分,就是我仍然修改默认的css加载程序,在“样式加载程序”之上使用“vue样式加载程序”。但是对于更大的更改(如vuetify),我可以为SASS/SCSS语法定义自己定义的加载程序


也许它可以进一步优化以消除重复,但只要它只有两种配置,我很高兴它可以工作:)

在最后问了一个问题之后,我遇到了一个github讨论:将使用新发现进行更新。我让它工作了,但感谢您的回答!强制加载程序将scss文件转换为缩进语法可能也会工作,以避免分号骗局!
选择。缩进语法将是一种解决方法sass loader 7:)你知道在不使用webpacker的项目中如何实现这一点吗?我没有environment.js文件,请看一下