With Angular 13 and the ng-packagr
when we publish SASS mixins with a library we need to add the library to exports in package.json
and also declare an assets
block in ng-package.json
.
These are the instructions.
https://github.com/ng-packagr/ng-packagr/blob/main/docs/copy-assets.md
And it is also explained in this issue: Tilde ~ in SCSS @use statement no longer resolving to node_modules as of Angular 13
So I've done that for this project: https://github.com/fireflysemantics/big-packaged-component-example
This is the ng-package.json
configuration:
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/big",
"assets": [
"./src/CHANGELOG.md",
"./src/lib/**/*.theme.scss"
],
"lib": {
"entryFile": "src/public-api.ts"
}
}
And this is the package.json
configuration:
{
"name": "@fireflysemantics/big-packaged-component-example",
"version": "0.0.7",
"exports": {
".": {
"sass": "./src/lib/big.component.theme.scss"
}
},
"peerDependencies": {
"@angular/common": "^13.3.0",
"@angular/core": "^13.3.0"
},
"dependencies": {
"tslib": "^2.3.0"
}
}
The project can be installed with NPM:
npm i @fireflysemantics/big-packaged-component-example
I've installed it into a test project: https://github.com/fireflysemantics/t/blob/master/src/styles.scss
And I'm trying to import the published theme with the declaration:
@use "@fireflysemantics/big-packaged-component-example/big.component.theme" as theme;
However it errors:
$ ng build
✔ Browser application bundle generation complete.
./src/styles.scss.webpack[javascript/auto]!=!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[5].rules[1].use[0]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[5].rules[1].use[1]!./src/styles.scss - Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Can't find stylesheet to import.
╷
3 │ @use "@fireflysemantics/big-packaged-component-example/big.component.theme" as theme;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
src/styles.scss 3:1 root stylesheet
./src/styles.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
HookWebpackError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Can't find stylesheet to import.
╷
3 │ @use "~@fireflysemantics/big-packaged-component-example/big.component.theme" as theme;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
src/styles.scss 3:1 root stylesheet
at tryRunOrWebpackError (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/HookWebpackError.js:88:9)
at __webpack_require_module__ (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5049:12)
at __webpack_require__ (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5006:18)
at /Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5077:20
at symbolIterator (/Users/oleersoy/Temp/sandbox/t/node_modules/neo-async/async.js:3485:9)
at done (/Users/oleersoy/Temp/sandbox/t/node_modules/neo-async/async.js:3527:9)
at Hook.eval [as callAsync] (eval at create (/Users/oleersoy/Temp/sandbox/t/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (/Users/oleersoy/Temp/sandbox/t/node_modules/tapable/lib/Hook.js:18:14)
at /Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:4984:43
at symbolIterator (/Users/oleersoy/Temp/sandbox/t/node_modules/neo-async/async.js:3482:9)
-- inner error --
Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Can't find stylesheet to import.
╷
3 │ @use "~@fireflysemantics/big-packaged-component-example/big.component.theme" as theme;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
src/styles.scss 3:1 root stylesheet
at Object.<anonymous> (/Users/oleersoy/Temp/sandbox/t/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[1]!/Users/oleersoy/Temp/sandbox/t/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[2]!/Users/oleersoy/Temp/sandbox/t/node_modules/resolve-url-loader/index.js??ruleSet[1].rules[5].rules[1].use[0]!/Users/oleersoy/Temp/sandbox/t/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[5].rules[1].use[1]!/Users/oleersoy/Temp/sandbox/t/src/styles.scss:1:7)
at /Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/javascript/JavascriptModulesPlugin.js:441:11
at Hook.eval [as call] (eval at create (/Users/oleersoy/Temp/sandbox/t/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
at Hook.CALL_DELEGATE [as _call] (/Users/oleersoy/Temp/sandbox/t/node_modules/tapable/lib/Hook.js:14:14)
at /Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5051:39
at tryRunOrWebpackError (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/HookWebpackError.js:83:7)
at __webpack_require_module__ (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5049:12)
at __webpack_require__ (/Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5006:18)
at /Users/oleersoy/Temp/sandbox/t/node_modules/webpack/lib/Compilation.js:5077:20
at symbolIterator (/Users/oleersoy/Temp/sandbox/t/node_modules/neo-async/async.js:3485:9)
Generated code for /Users/oleersoy/Temp/sandbox/t/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[1]!/Users/oleersoy/Temp/sandbox/t/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[5].rules[0].oneOf[0].use[2]!/Users/oleersoy/Temp/sandbox/t/node_modules/resolve-url-loader/index.js??ruleSet[1].rules[5].rules[1].use[0]!/Users/oleersoy/Temp/sandbox/t/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[5].rules[1].use[1]!/Users/oleersoy/Temp/sandbox/t/src/styles.scss
1 | throw new Error("Module build failed (from ./node_modules/sass-loader/dist/cjs.js):\nSassError: Can't find stylesheet to import.\n ╷\n3 │ @use \"~@fireflysemantics/big-packaged-component-example/big.component.theme\" as theme;\n │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n ╵\n src/styles.scss 3:1 root stylesheet");
Any ideas?
Update
So if I renamed big.component.theme.scss
to index.scss
and change the package.json
export to this:
"sass": "./src/lib/index.scss",
And import like this:
@use "@fireflysemantics/big-packaged-component-example/" as theme;
It works ... But is it a requirement to name the scss
file index
?
Also asked about this on the ng-packagr
repository:
https://github.com/ng-packagr/ng-packagr/issues/2337
CodePudding user response:
The sass resolvers used in ng-packagr
and @angular-devkit/build-angular:browser
supports package exports. In short, that means that you can't reach anything in the ~@fireflysemantics/big-packaged-component-example
package that isn't explicitly exported from the package.
This is what your package declares as exports:
// node_modules/@fireflysemantics/big-packaged-component-example/package.json
{
// ...
"exports": {
".": {
"sass": "./src/lib//big.component.theme.scss",
"types": "./fireflysemantics-big-packaged-component-example.d.ts",
"esm2020": "./esm2020/fireflysemantics-big-packaged-component-example.mjs",
"es2020": "./fesm2020/fireflysemantics-big-packaged-component-example.mjs",
"es2015": "./fesm2015/fireflysemantics-big-packaged-component-example.mjs",
"node": "./fesm2015/fireflysemantics-big-packaged-component-example.mjs",
"default": "./fesm2020/fireflysemantics-big-packaged-component-example.mjs"
},
"./package.json": {
"default": "./package.json"
}
},
// ...
}
There are only two exports in that package: .
and ./package.json
.
You can't import ~@fireflysemantics/big-packaged-component-example/big.component.theme
in your SASS file because ./big.component.theme
is not exported from the package.
Try adding the following to the exports of @fireflysemantics/big-packaged-component-example
.
"./big.component.theme": {
"sass": "./src/lib/big.component.theme.scss"
},
Now the SASS loader of angular's application builder can access the import and compilation will succeed.
You are not required to name the SASS file index.scss
or _index.scss
. In fact, you could name it anything you want (as long as it has a .scss
file extension).
The important bit is the key in the exports
object.