Compile scss with #import and $variables to rollupjs - node-sass

I'm compiling my first angular library using rollupjs and I need your help :)
Currently I have a structure like this:
.src
--components
--component1
--component1.ts
--component1.scss
--component1.html
--common
--_variables.scss
And my component1.scss looks like this
#import "../../core/sass/variables";
:host {
.trigger {
&.clear_btn {
color: $color-grey;
}
}
}
My variables.sccs looks like:
$color-grey-light: #e3e3e3;
$color-grey: #bfbfbf;
and my rollup.config.js looks like:
export default {
input: 'build/index.js',
output: {
file: 'dist/common.js',
format: 'es',
},
plugins: [
angular({
preprocessors: {
template: template => minifyHtml(template, htmlminOpts),
style: scss => {
const css = sass.renderSync({data: scss}).css;
return cssmin.minify(css).styles;
},
}
})
],
external: [
'#angular/core',
'#angular/animations',
'#angular/router',
'#angular/platform-browser',
'#angular/forms'
]
};
but when I execute I get this error:
[!] (angular plugin) Error: File to import not found or unreadable: ../../core/sass/variables.
Parent style sheet: stdin
build/app/components/toggle/toggle.component.js
Error: File to import not found or unreadable: ../../core/sass/variables.
Parent style sheet: stdin...
I tried adding importer from node-sass but to be honest I have no idea how to use it to compile everything into css and then inject it to my js (I can actually inject the scss into my template by using rollup-plugin-angular but I don't know how to compile scss)
Any help, tips or suggestions will be really appreciated :)

Related

vite without hash in filename

I'm trying to compile a webcomponent based on the monaco editor (in a lit element context). Having tried a lot of options I now have got the result down to two files
rmx-monaco.abc123.js
style.css
My top priority is to get rid of the hash (abc123), but I would also like to get down to a single file with the js and css in. Thanks in advance
My config reads:
import { resolve } from "path";
export default defineConfig({
base: "/",
build: {
rollupOptions: {
input:
// main: resolve(__dirname, "index.html"),
resolve(__dirname, "src/rmx-monaco.ts"),
output: {
// Prevent vendor.js being created
manualChunks: undefined,
// chunkFileNames: "zzz-[name].js",
// this got rid of the hash on style.css
assetFileNames: "assets/[name].[ext]",
},
},
// Prevent vendor.css being created
cssCodeSplit: false,
// prevent some warnings
chunkSizeWarningLimit: 60000,
},
});
My js entry files has these lines
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import { languages } from "monaco-editor/esm/vs/editor/editor.api";
import styles from "monaco-editor/min/vs/editor/editor.main.css";
(I can add more if it would help)
I needed to add output: {entryFileNames: "[name].js",...
Still working on getting a single file
add this:
export default defineConfig({
...
build: {
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`
}
}
}
})
Long time passed but for future viewers who visit this thread, try this package for single bundled .html file using ViteJS:
https://github.com/richardtallent/vite-plugin-singlefile

Jest cannot find module Vue/Vite

Jest Configuration:
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'vue'],
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/src/$1',
},
testEnvironment: 'jsdom',
testMatch: ['**/tests/unit/**/*.[jt]s?(x)'],
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.ts$': 'ts-jest',
},
}
My test file (.ts file) :
import { render } from '#testing-library/vue'
import Kaki from '~/components/Kaki.vue'
test('Kaki.vue', () => {
const { getByText } = render(Kaki)
getByText('Tono')
})
Here's my directory structure:
When I run the test, it says Cannot find module '~/components/Kaki.vue' or its corresponding type declarations.
I think it has something to do with moduleNameMapper
Can you check if it works if you change your Index.spec.ts to a .js file? The error you're getting is because TypeScript doesn't know what type should .vue files have.
In a new Vue CLI project, the error you're getting is prevented with the shims.d.ts which tells TS to treat *.vue files as if their default export had the Vue type.
The "correct" solution here is to figure out why isn't shims.d.ts telling TypeScript the type for *.vue files (which is why you're getting the "Cannot find module [...] or its corresponding type declarations" error
Another thing is - this is not a real solution but a temporary fix:
// #ts-ignore
import Kaki from '~/components/Kaki.vue'
Another thing you could try is importing Kaki with a relative path (so without the ~ alias)? The ~ alias may be broken in some way - are you sure the alias is correctly defined in your tsconfig.json?

Symfony: How to Import a Sass File into Every Vue Component

I am currently struggling with this. In my Symfony project I have a _variables.scss file, where I keep my global variables (e.g. colors).
This is included in my main scss file like this #import "variables"; - which works fine. Now I also use VueJs in my project and I would like to use my global variables inside Vue components. Now one way to achieve this is just importing the variables.scss itself:
//CustomButton.vue
<template>
...
</template>
<script>
export default {
name: "CustomButton"
}
</script>
<style lang="scss" scoped>
#import "../../scss/_variables.scss";
//able to use variables here
</style>
However with a growing project and different paths, this seems to be unnecessary work. What I'd like to achieve is to load the variables.scss into every Vue component automatically.
This is quite well explained here: [css-tricks.com - How to Import a Sass File into Every Vue Component in an App][1]
Sadly this does not work in my case (I think the vue.config.js is ignored completly) - the variables are still not usable inside the Vue component. I also tried to add the JavaScript into my main js file - where I load Vue - however this seems to break stuff (some module exception).
Is there any specific way to achieve this with symfony?
PS: I am using Symfony 5, Sass-Loader 9.0.1, Vue 2.6.12, Vue-Loader 15, Vue-Template-Compiler 2.6.12
[1]: https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/
Solution 1:
//webpack.config.js
.enableSassLoader(options => {
options.additionalData = `
#import "./assets/scss/_variables.scss"; //path.resolve is not working in my case to import the absolute path
`
})
```
Webpack config:
module.exports = {
...
module: {
rules: [
{
test: /\.scss$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
data: `
#import "functions";
#import "variables";
#import "mixins";
`,
includePaths: [
path.resolve(__dirname, "../asset/scss/framework")
]
}
}
]
},
]
}
this config imports 3 files: "_functions.scss", "_variables.scss", "_mixins.scss" from folder"../asset/scss/framework" and no need to use #import "../../scss/_variables.scss"; every time in your vue components. Maybe, you will adapt this webpack config to your needs or will get some idea to resolve your issue.
This is what you need c:
Since you are using Encore, modify your webpack.config.js, add this code
var Encore = require('#symfony/webpack-encore');
Encore.configureLoaderRule('scss', (loaderRule) => {
loaderRule.oneOf.forEach((rule) => {
rule.use.push({
loader: 'sass-resources-loader',
options: {
resources: [
// Change this url to your _variables.scss path
path.resolve(__dirname, './assets/app/styles/_vars.scss'),
]
},
})
})
})
You also are going to have to install sass-resources-loader
npm install sass-resources-loader
Then compile your code again and your sass variables will be available everywhere
Solution to my question:
//webpack.config.js
.enableSassLoader(options => {
options.additionalData = `
#import "./assets/scss/_variables.scss"; //path.resolve is not working in my case to import the absolute path
`
})
this will import the file in every sass template + vue component

Cant import JS library to my Nuxt project

I have weird problem.
I want use this hover-effect library (https://github.com/robin-dela/hover-effect) in my nuxt project.
This i have in my contact.vue in script tags
import hoverEffect from 'hover-effect'
export default {
mounted() {
const effect = new hoverEffect({
parent: document.querySelector('.right-section'),
intensity: 0.3,
image1: require('#/assets/images/1.jpg'),
image2: require('#/assets/images/2.jpg'),
displacementImage: require('#/assets/images/dist2.jpg'),
})
},
}
And that effect works perfectly.. BUT when i refresh the page i got this error:
SyntaxError Cannot use import statement outside a module
So i tried add this plugin into plugins/hover-effect.js
import Vue from 'vue'
import hoverEffect from 'hover-effect'
Vue.use(hoverEffect)
then in nuxt.config.js
plugins: [{ src: '~/plugins/hover-effect', mode: 'client' }],
But nothing works.. its always error: hoverEffect is not defined. I tried another 20 ways with no success. I tried this effect in normal Vue project and it works but not in nuxt.js. Can somebody help me with this?
You can configure it in the head of the page:
Page.vue
export default {
head() {
return {
script: [
{src: '../dist/hover-effect.umd.js'}
]
}
},
...
mounted() {
const effect = new hoverEffect({
parent: document.querySelector('.right-section'),
intensity: 0.3,
image1: require('#/assets/images/1.jpg'),
image2: require('#/assets/images/2.jpg'),
displacementImage: require('#/assets/images/dist2.jpg'),
})
},
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
// Doc: https://github.com/nuxt/content
'#nuxt/content',
'hover-effect'
],
Have you tried to add hover-effect library to modules in nuxt.config.js file? All I did was install the package and add it to the module and then have the same code as your script tag. Hope it helped you!

VueJS build started throwing Error: Conflict: Multiple assets emit to the same filename

My app used to work fine until I updated VueJS this morning. Now when I build, it shows the following error:
Error: Conflict: Multiple assets emit to the same filename img/default-contractor-logo.0346290f.svg
There's only one file like this in the repo.
Here's my vue.config.js:
module.exports = {
baseUrl: '/my/',
outputDir: 'dist/my',
css: {
loaderOptions: {
sass: {
data: `
#import "#/scss/_variables.scss";
#import "#/scss/_mixins.scss";
#import "#/scss/_fonts.scss";
`
}
}
},
devServer: {
disableHostCheck: true
}
};
I tried webpack fixes recommended in similar cases, but non helped.
I had the same error when importing SVG files using dynamically generated path in the require statement:
const url = require("../assets/svg/#{value}");
<img src={{url}} />
In this case file-loader processes all SVG files and saves them to the output path. My file-loader options were:
{
loader: "file-loader",
options: { name: "[name].[ext]" }
}
The folders structure has duplicate file names, something like this:
assets
|__ one
|____ file.svg
|__ two
|____ file.svg
In this case file-loader saves both file.svg files to the same output file: build/assets/file.svg - hence the warning.
I managed to fix it by adding [path] to the name option:
{
loader: "file-loader",
options: { name: "[path][name].[ext]" }
}
The answer by #ischenkodv is definitely correct, but because of my inexperience with webpack, I needed a little more context to use the information to fix the problem.
For the benefit of anyone else in the same situation, I'm adding the following details which I hope will be useful.
This section of the Vue.js documentation was particularly helpul:
VueJS - Modifying Options of a Loader
For the TL;DR fix, here is the relevant chunk of my vue.config.js:
// vue.config.js
module.exports = {
// ---snip---
chainWebpack: config =>
{
config.module
.rule('svg')
.test(/\.svg$/)
.use('file-loader')
.tap(options =>
{
return { name: "[path][name].[ext]" };
});
}
// ---snip---
};
In my project it was the flag-icon-css NPM package that was causing the Multiple assets emit to the same filename conflict errors. The above update to the vue.config.js file resolved the problem for me.
I suspect that the regular expression in the test could be tightened up to target just the items in the flag-icon-css package rather than matching all SVG files, but I haven't bothered since it's not causing any adverse effects so far.