Include node_modules css in Vuejs application that uses scss - css

I have deployed my application to aws and I see that the application renders fine, except that the syncfusion controls do not render correctly. Google chrome console does not show any errors.
The application renders correctly in my local machine.
To fix this, it was suggested I move the import '#syncfusion/**/styles/material.css' statements in the individual vue component to App.vue (as documented here). I however get a "Failed to resolve loader: sass-loader, You may need to install it" error(the application has node-sass, sass-loader installed already).
How should I include css files along with scss files, in my application?
Before: vocabulary.vue:
<script>
import '#syncfusion/ej2-base/styles/material.css';
import '#syncfusion/ej2-vue-inputs/styles/material.css';
package.json:
"devDependencies": {
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
}
vue.config.js:
module.exports = {
publicPath: '/',
transpileDependencies: [
'vue-echarts',
'resize-detector'
],
configureWebpack: {
devtool: 'source-map',
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
}
App.Vue:
<style>
#import "../node_modules/#syncfusion/ej2-base/styles/material.css";
#import "../node_modules/#syncfusion/ej2-vue-inputs/styles/material.css";
</style>

Deleting the npm packages and re-installing them again fixed the issue.

Related

Using vite plugins with Storybook and SvelteKit

I have successfully set up #poppanator/sveltekit-svg with SvelteKit using the following configuration (svelte.config.js):
import preprocess from 'svelte-preprocess';
import svg from '#poppanator/sveltekit-svg';
/** #type {import('#sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
vite: {
plugins: [svg()]
}
}
};
export default config;
This works when running the SvelteKit project using npm run dev. However, I cannot get the svg plugin to work inside Storybook.
I have the following Storybook configuration (.storybook/main.cjs):
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx|svelte)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-svelte-csf"
],
"core": {
"builder": "storybook-builder-vite"
},
"svelteOptions": {
preprocess: import("../svelte.config.js").preprocess
}
}
When importing SVG files in Storybook stories (or in components used by the stories), only the file path of the SVG file is returned. When importing SVG files inside a SvelteKit route, a Svelte component is returned as it should be.
I have tried this with Storybook 6.3.10 and 6.4.0-beta.7 with storybook-builder-vite (0.1.0).
How should this go together to make SVG imports work inside Storybook?
While SvelteKit uses Vite, Storybook uses Webpack.
To get svg imports working you'll need to find a loader for webpack that behaves similar to the #poppanator/sveltekit-svg plugin and add that to your storybook configuration.
I'm not sure similar loader exists (yet), depending on your usage, renaming the .svg files to .svelte could be an alternative

Set Global Styles Without Class Hashing in Nuxt

I have numerous Vue SPAs in a monorepo that all share a common set of global styles, each SPA and the styles are their own package.json workspace. I'm trying to replace one of them with Nuxt.
The global styles are .scss files, they import Vue bootstrap and have some custom variables and classes.
As such, I did a fresh install of Nuxt and then ran:
yarn add -D sass sass-loader#10 fibers
I know I can get global styles like so:
//in nuxt.config.js:
css: [resolve(__dirname+'/../common/styles/index.scss')
Really I thought that should/would be it, and I see it does get injected into the page. However, the class names are hashed, so it doesn't apply to my components.
Instead of this (fake css to test if it goes in the page):
.test{
text-align: test;
top: test;
}
I get this:
.olAmdkaWN_JnK1npjbKiI {
text-align: test;
top: test;
}
How can I stop the global styles from being hashed like this, especially when I may be importing components from the other SPAs/common and their classnames aren't being hashed in the HTML? Only the injected global styles are getting hashed like this.
I've tried various attempts at setting the localIdentName such as:
//in nuxt.config.js
build: {
extend(config) {
config.module.rules.push({
test: /\.scss$/,
use: [{
loader: 'css-loader',
options: {
modules: false
/*
or sometimes I'll try something like:
modules:{
localIdentName: '[local]'
}
*/
}
},
{
loader: 'sass-loader'
}
]
})
},
I've also set:
cssModules: {
localIdentName: '[local]'
},
Again in the nuxt.config.js. But nothing works and furthermore I think I must have a conceptual error about how global styles are meant to work, as I feel like I'm fighting the framework rather than working with it.
My nuxt, webpack and sass-loader verisons are as follows:
nuxt#2.15.4
webpack#4.46.0
sass-loader#10.1.1 (It was at 7.1.x but the console suggested upgrading it - didn't make a difference in terms of solving this)
package.json:
"dependencies": {
"core-js": "^3.9.1",
"common": "1.0.0", (local dependency)
"nuxt": "^2.15.3"
},
"devDependencies": {
"fibers": "^5.0.0",
"sass": "^1.32.11",
"sass-loader": "10"
}
Turns out all I needed was this (the key was to put it in loaders within build):
//in nuxt.config.js
build: {
loaders: {
cssModules: {
localIdentName: '[local]'
},
},
}
Please note this only works if you properly install your dependencies and heed build warnings in regards to css-loader and sass-loader. I tried downgrading sass-loader and this didn't work until I put it back at "10" which is what Nuxt expected (threw a warning).

Add SCSS support to Vue project

In my packages.json file by default I get:
"postcss": {
"plugins": {
"autoprefixer": {}
}}
When I add <style lang='scss'> It doesn't compile like magic like it does for Typescript support. I know I will need to specify some NPM package as devDependencies and specify something above in the postcss section to get scss to compile, but I can't find any documentation outside of webpack so I am lost.
See https://vue-loader.vuejs.org/guide/pre-processors.html.
For example, to compile our <style> tag with SASS/SCSS:
npm install -D sass-loader node-sass
In your webpack config:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
Now in addition to being able to import 'style.scss', we can use SCSS
in Vue components as well:
<style lang="scss"> /* write SCSS here */ </style>
Any content inside the block will be processed by webpack as if it's
inside a *.scss file.

How to add global style to angular 6/7 library

I was trying to add global styles in the same way like in angular app, but it totally does not work.
My libraries' name is example-lib, so I added styles.css to /projects/example-lib/. I added styles in main angular.json file:
...
"example-lib": {
"root": "projects/example-lib",
"sourceRoot": "projects/example-lib/src",
"projectType": "library",
"prefix": "ngx",
"architect": {
"build": {
"builder": "#angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "projects/example-lib/tsconfig.lib.json",
"project": "projects/example-lib/ng-package.json",
"styles": [
"projects/example-lib/styles.css" <!-- HERE
],
},
...
But when I tried build library using command:
ng build example-lib
I got error:
Schema validation failed with the following errors:
Data path "" should NOT have additional properties(styles)
I guess that is the other way to add global styles in separate library. Anyone can help me?
I have a workaround for this. Just create the root component of your library without view encapsulation and all its styles will be then global.
my-library.component.ts
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'lib-my-library',
templateUrl: './my-library.component.html',
styleUrls: ['./my-library.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class MyLibraryComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
my-library.component.html
<!-- html content -->
my-library.component.scss
#import './styles/core.scss';
Now your my-library.component.scss and core.scss are global
styles/core.scss
body {
background: #333;
}
core.scss is optional, I just like to keep the root files clean.
Update: In case you want your mixins and variables too, then follow this answer.
As #codeepic already pointed out, there is currently a standard solution.
In ng-package.json add
"assets": ["./styles/**/*.css"]
The provided paths should be the paths to your files. At the same time, they will be the paths inside your /dist folder.
On build, the files will be copied to /dist. Users of your library will be able to add them to their global styles as follows.
/* styles.css */
#import url('node_modules/<your-library-name>/styles/<file-name>');
This way you can copy any type of files.
P.S. When used with CSS, do not forget that you can create an index.css file that can be imported just like node_modules/<your-library-name>/styles.
From Compiling css in new Angular 6 libraries:
install some devDependencies in our library in order to bundle the css:
ng-packagr
scss-bundle
ts-node
Create css-bundle.ts:
import { relative } from 'path';
import { Bundler } from 'scss-bundle';
import { writeFile } from 'fs-extra';
/** Bundles all SCSS files into a single file */
async function bundleScss() {
const { found, bundledContent, imports } = await new Bundler()
.Bundle('./src/_theme.scss', ['./src/**/*.scss']);
if (imports) {
const cwd = process.cwd();
const filesNotFound = imports
.filter(x => !x.found)
.map(x => relative(cwd, x.filePath));
if (filesNotFound.length) {
console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
throw new Error('One or more SCSS imports failed');
}
}
if (found) {
await writeFile('./dist/_theme.scss', bundledContent);
}
}
bundleScss();
Add _theme.scss inside the /src directory of the library that actually contains and imports all the css that we want to bundle.
Add postbuild npm script to run the css-bundle.ts
Include it in the styles tag in your Application in the angular.json
From this issue solution
Install cpx and scss-bundle as Dev dependencies to your package.json. Then add the following entries in your package.json "scripts" property:
"scripts": {
...
"build-mylib": "ng build mylib && npm run build-mylib-styles && npm run cp-mylib-assets",
"build-mylib-styles": "cpx \"./projects/mylib/src/lib/style/**/*\" \"./dist/mylib/style\" && scss-bundle -e ./projects/mylib/src/lib/style/_style.scss -d ./dist/mylib/style/_styles.scss",
"cp-mylib-assets": "cpx \"./src/assets/**/*\" \"./dist/mylib/assets\"",
...
}
Replace "mylib" with your real library name and then just run in your terminal build-mylib. That would compile your scss assets to your dist folder.
You use this global styles in your actual Angular project just import them in your angular.json file within your project settings:
"styles": [
"src/styles.scss",
"dist/my-shiny-library/_theme.scss"
],
(use dist if your project is in the same workspace, or node_moduled if its an imported library)
1- be sure you are putting your styles inside the library
example:
projects/your-lib-name/assets/styles.css
2- then in your ng-package.json (in the lib for sure) put the assets rule
{
"$schema": ... ,
"dest": ... ,
> "assets": [
> "./assets/*"
> ],
"lib": ...
}
3-
in your application, you can use this asset
"styles": [
"../your-lib-name/assets/styles.css"
]
this is a tutorial

Webpack 2: compile SASS and ignore "Module not found: Error: Can't resolve './assets/image.png'"

I'm trying to use Webpack instead of Gulp as a task runner, in this case simply compiling all SCSS files as I was doing it with Compass before. The main objectives are:
run Autoprefixer and generate separate CSS file for each SCSS that is not a partial
don't bundle images or concatenate CSS files
keep image urls as is, e.g. background-image: url(assets/image.png)
don't throw errors if images cannot be found
#1 is solved and working, however it stops working and throws an error as soon as the SCSS links to an image as in #3 above:
ERROR in ./~/css-loader!./~/postcss-loader!./~/sass-loader/lib/loader.js!./scss/style.scss
Module not found: Error: Can't resolve './assets/image.png' in 'C:\Users\robro\projects\...\my-project\dev\styles\scss
# ./~/css-loader!./~/postcss-loader!./~/sass-loader/lib/loader.js!./scss/style.scss 6:15328-15369
# ./scss/style.scss
I'd like to "simply" ignore that error and not having to copy the missing files to my local hard drive. That's mostly just me being stubborn, thinking "Compass didn't need those images to be present, why does Webpack?"
Here's my setup:
webpack.config.js
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var ExtractCSS = new ExtractTextPlugin('css/[name]');
module.exports = {
entry: {
'style.css': './scss/style.scss',
'admin.css': './scss/admin.scss'
},
output: {
filename: './css/[name]'
},
module: {
rules: [
{
test: /\.scss$/,
use: ExtractCSS.extract({
fallback: "style-loader",
use: [
"css-loader",
"postcss-loader",
"sass-loader"
]
})
},
{ test: /\.(jpg|jpeg|png|svg|gif|woff|woff2|otf|ttf)$/, use: 'ignore-loader' }
]
},
plugins: [
ExtractCSS
],
watch: true
};
package.json
{
"dependencies": {},
"devDependencies": {
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^2.0.0-rc.3",
"ignore-loader": "^0.1.2",
"node-sass": "^4.5.0",
"postcss-loader": "^1.3.0",
"sass-loader": "^6.0.0",
"style-loader": "^0.13.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0"
}
}
As you can see, i tried using ignore-loader to stop sass-loader from complaining about missing images, but to no avail. To be honest, I'm not even sure this is how it's intended to be used.
As soon as I remove any line that links to images from the SCSS, everything is working just fine: style.css and admin.css get built, autoprefixed and dropped into css/ folder. Now I want to keep it that way, but also use styles like background-image: url(assets/image.png) without webpack complaining about those images not being present on the file system.
Case closed: Webpack is NOT a task runner. Blog posts naming Webpack as a successor to Grunt or Gulp or fail to explicitly point out that these tools may have some overlapping features but in the end have very different goals. Grunt and Gulp are task runners and Webpack is an asset bundler. Trying to make Webpack not bundle your assets defeats it's main purpose and one's better off choosing a different tool.

Resources