Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using "less" in vue single component file and "px2rem-loader", it will report "undefined missing '}'" error #1706

Closed
sengmitnick opened this issue Jun 29, 2018 · 6 comments
Labels

Comments

@sengmitnick
Copy link

Version

3.0.0-rc.3

Reproduction link

https://github.com/smk17/px2rem-vue-demo

Steps to reproduce

在命令窗口执行以下命令:
Execute the following command in the command window:

git clone https://github.com/smk17/px2rem-vue-demo.git
cd px2rem-vue-demo
yarn
yarn serve

What is expected?

正确运行并px已经转成rem
Runs correctly and px has changed to rem

What is actually happening?

实际报错:
Actual error:

yarn run v1.3.2
$ vue-cli-service serve
 INFO  Starting development server...
 94% after seal

 ERROR  Failed to compile with 1 errors                                                                                                                       14:57:02

 error  in ./src/App.vue?vue&type=style&index=0&lang=less

Module build failed (from ./node_modules/px2rem-loader/index.js):
Error: undefined:28:3: missing '}'
    at error (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:62:15)
    at declarations (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:260:26)
    at rule (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:561:21)
    at rules (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:118:70)
    at stylesheet (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:81:21)
    at Object.module.exports [as parse] (/Users/smk17/VsCode/hello-world/node_modules/css/lib/parse/index.js:565:20)
    at Px2rem.generateRem (/Users/smk17/VsCode/hello-world/node_modules/px2rem/lib/px2rem.js:70:20)
    at Object.module.exports (/Users/smk17/VsCode/hello-world/node_modules/px2rem-loader/lib/px2rem-loader.js:7:20)

 @ ./node_modules/vue-style-loader??ref--10-oneOf-1-0!./node_modules/css-loader??ref--10-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--10-oneOf-1-2!./node_modules/less-loader/dist/cjs.js??ref--10-oneOf-1-3!./node_modules/px2rem-loader??ref--10-oneOf-1-4!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&lang=less 4:14-473 14:3-18:5 14:473-18:4 15:22-481
 @ ./src/App.vue?vue&type=style&index=0&lang=less
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.0.128:8081/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

分析该错误的发生:

  1. 发生该错误的根本原因:在less中使用样式嵌套就会发生该错误,如果不使用就完全没问题
  2. 导致该错误出现的可能:css-loader和less-loader对vue单文件组件的样式处理顺序
  3. 目前的规避方法:把vue单文件组件的less样式放到单独的less文件,然后通过<style src="./App.less"></style>的方式引用即可。
    Analyze the occurrence of this error:
  4. The root cause of the error: This error occurs when you use style nesting in less. If you don't use it, you have no problem at all.
  5. Possible causes of this error: css-loader and less-loader style handling of vue single file components
  6. Current avoidance methods: Put the less style of the vue single file component into a separate less file, and then refer to it via <style src="./App.less"></style>
@u3u
Copy link

u3u commented Jun 29, 2018

建议你使用 postcss-plugin-px2rem,在我这里良好运行 :)

@sengmitnick
Copy link
Author

sengmitnick commented Jun 30, 2018

@u3u 关键是在一些庞大的旧项目,并不是简单的替换就可以解决的,还是需要从根本入手解决

@sengmitnick sengmitnick changed the title 在vue单组件文件中使用less,再使用px2rem-loader时,会报undefined missing '}'错误 When using "less" in vue single component file and "px2rem-loader", it will report "undefined missing '}'" error Jun 30, 2018
@Akryum Akryum added bug needs team repro We acknowledged your report and will soon try to reproduce it labels Jun 30, 2018
@LinusBorg
Copy link
Member

LinusBorg commented Jul 1, 2018

The way you are adding the loader, it's added as the first loader to run, but it doesn't understand less.

it has to run after less-loader has run, so it has to be added before it, or even better, before postcss-loader.

Output of vue-cli-service inspect before this change (shortened):

/* config.module.rule('less').oneOf('vue') */
{
  resourceQuery: /\?vue/,
  use: [
    /* config.module.rule('less').oneOf('vue').use('vue-style-loader') */
    {
      loader: 'vue-style-loader',
      options: {
        sourceMap: false,
        shadowMode: false
      }
    },
    /* config.module.rule('less').oneOf('vue').use('css-loader') */
    {
      loader: 'css-loader',
      options: {
        minimize: false,
        sourceMap: false,
        importLoaders: 3
      }
    },
    /* config.module.rule('less').oneOf('vue').use('postcss-loader') */
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: false
      }
    },
    /* config.module.rule('less').oneOf('vue').use('less-loader') */
    {
      loader: 'less-loader',
      options: {
        sourceMap: false
      }
    },
     /* config.module.rule('less').oneOf('vue').use('px2rem-loader') */
    {
      loader: 'px2rem-loader',
      options: {
        remUnit: 75,
        remPrecision: 8
      }
    },
  ]
},

Solution

config.module
  .rule(loader)
  .oneOf('vue')
  .use('px2rem-loader')
  .loader('px2rem-loader')
  .before('postcss-loader') // this makes it work.
  .options({ remUnit: 75, remPrecision: 8 })
  .end()

Output of vue-cli-service inspect after this change (shortened):

/* config.module.rule('less').oneOf('vue') */
{
  resourceQuery: /\?vue/,
  use: [
    /* config.module.rule('less').oneOf('vue').use('vue-style-loader') */
    {
      loader: 'vue-style-loader',
      options: {
        sourceMap: false,
        shadowMode: false
      }
    },
    /* config.module.rule('less').oneOf('vue').use('css-loader') */
    {
      loader: 'css-loader',
      options: {
        minimize: false,
        sourceMap: false,
        importLoaders: 3
      }
    },
    /* config.module.rule('less').oneOf('vue').use('px2rem-loader') */
    {
      loader: 'px2rem-loader',
      options: {
        remUnit: 75,
        remPrecision: 8
      }
    },
    /* config.module.rule('less').oneOf('vue').use('postcss-loader') */
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: false
      }
    },
    /* config.module.rule('less').oneOf('vue').use('less-loader') */
    {
      loader: 'less-loader',
      options: {
        sourceMap: false
      }
    }
  ]
},

@LinusBorg LinusBorg added question and removed bug needs team repro We acknowledged your report and will soon try to reproduce it labels Jul 1, 2018
@sengmitnick
Copy link
Author

@LinusBorg perfect

@StrangeYear
Copy link

@LinusBorg It is very good, tks.

@Ga-O
Copy link

Ga-O commented Apr 9, 2019

loader is not defined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants