Skip to content

SASS files from NPM modules referencing relative imports won't build #4053

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

Open
christophehenry opened this issue May 24, 2019 · 21 comments · May be fixed by #6444
Open

SASS files from NPM modules referencing relative imports won't build #4053

christophehenry opened this issue May 24, 2019 · 21 comments · May be fixed by #6444

Comments

@christophehenry
Copy link

Version

3.7.0

Reproduction link

https://github.com/christophehenry/mrt

Environment info

Environment Info:

  System:
    OS: Linux 5.0 Fedora 28 (Twenty Eight) 28 (Twenty Eight)
    CPU: (8) x64 Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
  Binaries:
    Node: 8.11.3 - ~/.nvm/versions/node/v8.11.3/bin/node
    Yarn: 1.7.0 - /usr/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v8.11.3/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: 66.0.4
  npmGlobalPackages:
    @vue/cli: 3.7.0

Steps to reproduce

git clone https://github.com/christophehenry/mrt.git && cd mrt
npm i
npm run test:unit

What is expected?

Test run correctly

What is actually happening?

sass-loader will crash with error stating relative imports of NPM module can't be found.


Full stacktrace:

WEBPACK  Failed to compile with 1 error(s)

Error in ./src/components/HelloWorld.vue?vue&type=style&index=0&id=469af010&scoped=true&lang=scss&

  Module build failed (from ./node_modules/sass-loader/lib/loader.js):
  Can't find stylesheet to import.
    ╷
  8 │ @import "functions";
    │         ^^^^^^^^^^^
    ╵
    ./mrt/node_modules/bootstrap/scss/bootstrap.scss 8:9  @import
    stdin 1:9                                                           root stylesheet
        in http:/localhost/$HOME/mrt/node_modules/bootstrap/scss/bootstrap.scss (line 8, column 9)

 ERROR  mocha-webpack exited with code 1.
@nicojs
Copy link

nicojs commented Jun 12, 2019

I think I've got the same issue. Styles load normal for build/serve, however they cannot resolve for unit testing with mocha.

Reproduction with a fresh vue cli project:

  1. vue create hello-world
  2. Choose mocha unit tests and sass (dart-sass).
  3. Add a file "src\style\main.scss"
  4. Import it from "src\components\HelloWorld.vue": @import '../style/main';
  5. run npm run test:unit. You'll get the error.

Does anyone have any idea why? I've been debugging for a few hours, no clue why it's not working.

@publicFunction
Copy link

publicFunction commented Jul 2, 2019

Confirming seeing the same issue using the ~@ shortcut...

@import "~@/scss/color";
@import "~@/scss/mixins";

.auth {
  display: flex;
  flex-direction: column;
  flex: 0 0 100%;
  justify-content: flex-start;
  align-content: center;
  width: 100%;
  z-index: 5;
...

package.json

"devDependencies": {
    "@types/chai": "^4.1.0",
    "@types/mocha": "^5.2.4",
    "@vue/cli-plugin-babel": "^3.8.0",
    "@vue/cli-plugin-e2e-cypress": "^3.8.0",
    "@vue/cli-plugin-typescript": "^3.8.0",
    "@vue/cli-plugin-unit-mocha": "^3.8.0",
    "@vue/cli-service": "^3.8.0",
    "@vue/test-utils": "1.0.0-beta.29",
    "chai": "^4.1.2",
    "lint-staged": "^8.1.5",
    "sass": "^1.18.0",
    "sass-loader": "^7.1.0",
    "typescript": "^3.4.3",
    "vue-svg-loader": "^0.12.0",
    "vue-template-compiler": "^2.6.10"
  },

@grandsilence
Copy link

the same issue

@grandsilence
Copy link

grandsilence commented Jul 6, 2019

the same issue

Fix: just remove special characters and spaces from project path ("C#" name of folder for example renamed to CSharp).

@Kawemi
Copy link

Kawemi commented Jul 8, 2019

Same problem, and I've been looking for a couple of hours and no success. My path doesn't contain any special characters, as @grandsilence suggested.

@StepanOmelchenko
Copy link

same issue

1 similar comment
@destinytaoer
Copy link

same issue

@mortenpohlers
Copy link

same issue, I do not have special characters in my path, either (using debian/linux). Any solution or workaround?

@lujunpeng
Copy link

I also encountered the same problem, but there is no problem with node-sass.

@LbISS
Copy link

LbISS commented Aug 23, 2019

I'm having the same issue in new project. Created structure using vue-cli/sass/mocha. Have global design-tokens.scss which connected in vue.config.js:

module.exports = {
	css: {
		loaderOptions: {
			sass: {
				data: `@import "~@/styles/design-tokens.scss";`
			}
		}
	}
}

It's working just fine when using serve/build, but unit-tests (yarn test:unit) throwing an error:

 Can't find stylesheet to import.
 │ @import "~@/styles/design-tokens.scss";

Anyone has solved the issue? It seems strange that in such large well-known project unit-tests with scss just not working and an issue is open for a few month.

@nicojs
Copy link

nicojs commented Aug 27, 2019

The only valid workaround I know of is using node-sass instead of dart-sass (with the disadvantages it comes with).

@robbishop
Copy link

robbishop commented Oct 21, 2019

I think the issue relates to how mocha-webpack handles webpack CSS Preprocessors. https://github.com/zinserjan/mocha-webpack/blob/master/docs/installation/webpack-configuration.md

The document suggests replacing all CSS modules with a null-loader. A bit of tracing showed that the vue-cli basically executes the following command when running a unit test:

npx mocha-webpack \
--recursive \
--require node_modules/@vue/cli-plugin-unit-mocha/setup.js \
--webpack-config node_modules/@vue/cli-service/webpack.config.js \
'tests/unit/**/*.spec.js'

The file node_modules/@vue/cli-service/webpack.config.js generates the webpack config and passes it into mocha. To intercept and replace CSS Preprocessor modules with the null-loader I created a wrapper.

/* fix-webpack.config.js */
// eslint-disable-next-line import/no-extraneous-dependencies
const vueCliWebpack = require('@vue/cli-service/webpack.config');

vueCliWebpack.module.rules = vueCliWebpack.module.rules.map((rule) => {
  const regExpStr = rule.test.toString();
  if (regExpStr === '/\\.sass$/' || regExpStr === '/\\.scss$/') {
    return {
      test: rule.test,
      loader: 'null-loader',
    };
  }
  return rule;
});
module.exports = vueCliWebpack;

(note: you need to install the null-loader and possibly edit the rule tests to requirements)
I couldn't find a way of forcing vue-cli-service test:unit to use my version of the generator but the following command works.

npx mocha-webpack \
--recursive \
--require node_modules/@vue/cli-plugin-unit-mocha/setup.js \
--webpack-config fix-webpack.config.js \
'tests/unit/**/*.spec.js'

I'm using this as a temporary workaround. The good part is that its is much quicker to run tests without having to run CSS Preprocessors. However I still don't understand the root cause of the failure and this workaround does not run in the context of the vue-cli.

@robbishop
Copy link

Just occurred to me that this change can be made using webpack chaining.
https://cli.vuejs.org/guide/webpack.html#chaining-advanced

// vue.config.js
module.exports = {
  chainWebpack: (config) => {
    if (process.env.NODE_ENV === 'test') {
      const scssRule = config.module.rule('scss');
      scssRule.uses.clear();
      scssRule
        .use('null-loader')
        .loader('null-loader');
    }
  },
};

Not perfect but than the previous attempt

@ialmost
Copy link

ialmost commented Oct 28, 2019

The only valid workaround I know of is using node-sass instead of dart-sass (with the disadvantages it comes with).

You are right,The solution can also be @import "../~styles/_varibles.scss";

@anlexN
Copy link

anlexN commented Nov 2, 2019

i don’t want to use any framework integration or wrapper!
How to use material-components-web?

@JoshPJackson
Copy link

I'm having this problem using laravel-mix. Anyone here been able to fix it?

@anlexN
Copy link

anlexN commented Nov 11, 2019

https://material.io/develop/web/docs/getting-started/
look at appendix at the bottom of document
Appendix: Configuring a Sass Importer for Nested node_modules

@ferk6a
Copy link

ferk6a commented Jan 28, 2020

Came across this today, this bug still exists. Used @robbishop's solution and it seems to work.

  • @vue/cli-plugin-unit-mocha: 4.1.2
  • @vue/cli-service: 4.1.2
  • Node: 13.7.0
  • Npm: 6.13.6

@larshp
Copy link

larshp commented Mar 2, 2020

same issue, solved by

removing

  css: {
    extract: {
      filename: "[name].css",
      chunkFilename: "[name].css"
    }
  },

from vue.config.js

@amadeann
Copy link

I'm having this problem using laravel-mix. Anyone here been able to fix it?

@JoshPJackson

Here's what worked for me based on robbishop's solution:

if (process.env.NODE_ENV !== "testing") {
    mix.version();
}

if (process.env.NODE_ENV === "testing") {
    const nodeExternals = require("webpack-node-externals");

    mix.webpackConfig((webpack) => {
        return {
            devtool: "inline-cheap-module-source-map",
            externals: [nodeExternals()],
            module: {
                rules: [
                    {
                        test: /\.scss/,
                        use: "null-loader",
                    },
                ],
            },
        };
    });
}

This assumes that your test script in package.json sets env to testing as in:
"test": "cross-env NODE_ENV=testing mochapack --webpack-config node_modules/laravel-mix/setup/webpack.config.js --require test/setup.js test/**/*.spec.js",

@agoalofalife
Copy link

the same issue

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

Successfully merging a pull request may close this issue.