Rollup import CSS as constructible CSSStyleSheet - vite

I'm switching my project from webpack to vite. Before I imported css as the new constructible stylesheets CSSStyleSheet(). This allows passing it directly to a web components adopted stylesheet:
import styles from './styles.css';
class MyComponent extends HTMLElement {
constructor() {
super();
this.shadowRoot.adoptedStyleSheets = [styles];
}
}
In webpack, you can configure the css-loader to export to constructible style sheets:
{
test: /\.css$/i,
use: [
{
loader: 'css-loader',
options: {
exportType: 'css-style-sheet',
modules: false,
},
},
],
},
How can I do this in rollup without having to change my code?

Related

Spartacus 3.1 new installation shows blank page

I have followed below steps to create Spartacus storefront,
ng new spartacus3
cd spartacus3
ng add #spartacus/schematics --baseUrl https://spartacus-demo.eastus.cloudapp.azure.com:8443/ --baseSite=electronics-spa --ssr
yarn install
yarn start
It installs Angular 10.2.4 and Spartacus 3.1.
It compiles without error.
But am getting blank screen when I'm opening same in browser using URL http://localhost:4200/
I verified network tab in browser it have valid response.
Here is network tab screenshot - screenshot - 1, screenshot 2
But no one elements are getting added in DOM.
Here is elements tab screenshot - elements tab screenshot
But in console I have below info,
spartacus-storefront.js:17341 No component implementation found for the CMS component type 'ProfileTagScriptComponent'.Make sure you implement a component and register it in the mapper .
Console tab screenshot
I followed below link,
https://sap.github.io/spartacus-docs/schematics/#adding-spartacus-core-libraries-and-features-to-your-angular-project
Please help me to get working Spartacus app in my local.
Below is my app.module.ts code,
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { translations, translationChunksConfig } from '#spartacus/assets';
import { B2cStorefrontModule } from '#spartacus/storefront';
import { StoreFinderRootModule } from '#spartacus/storefinder/root';
import { provideConfig } from '#spartacus/core';
import { storeFinderTranslations } from '#spartacus/storefinder/assets';
import { storeFinderTranslationChunksConfig } from '#spartacus/storefinder/assets';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
B2cStorefrontModule.withConfig({
featureModules: {
storeFinder: {
module: () => import('#spartacus/storefinder').then(
(m) => m.StoreFinderModule
),
},
},
backend: {
occ: {
baseUrl: 'https://spartacus-demo.eastus.cloudapp.azure.com:8443',
prefix: '/occ/v2/'
}
},
context: {
currency: ['USD'],
language: ['en'],
},
i18n: {
resources: translations,
chunks: translationChunksConfig,
fallbackLang: 'en'
},
features: {
level: '3.0'
}
}),
StoreFinderRootModule
],
providers: [
provideConfig({
i18n: {
resources: storeFinderTranslations,
chunks: storeFinderTranslationChunksConfig,
},
})],
bootstrap: [AppComponent]
})
export class AppModule { }
Once added below config in app.module, then app works fine,
{
provide: ROUTER_CONFIGURATION,
useValue: {
scrollPositionRestoration: 'enabled',
}
}
This code snip is not required for Spartacus version above/= 3.2 as the app have new structure.
In app.module.ts use this baseUrl link baseUrl: 'https://spartacus-training.eastus.cloudapp.azure.com:8443',

How to get SCSS variables into react

I followed this post How to use SCSS variables into my React components or this one React and SCSS export a variable from scss to react to get scss variable in my react app but it does not work.
myvar.scss file:
$color: red;
:export {
color: $color;
}
.myclass {
background-color: $color;
}
App.js file:
import variables from './myvar.scss';
const App = () => {
console.log(variables);
return <div className="myclass">Hello</div>
}
export default App;
The div background is red, so myvar.scss is working. But variables is an empty object.
(react version : 17.0.1)
node_modules\react-scripts\config\webpack.config.js
module: {
strictExportPresence: true,
rules: [
{ parser: { requireEnsure: false } },
{
oneOf: [
...
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
'sass-loader'
),
sideEffects: true,
},
UPDATE: The original answer claims that it is only supported by webpack, but this is no longer true. Many bundlers now support this via their own css processing pipeline.
Original Answer:
That's a webpack/css-loader feature and only works with webpack and css-loader (https://webpack.js.org/loaders/css-loader/#separating-interoperable-css-only-and-css-module-features)
Important: the :export syntax in your SCSS/CSS files will only work for those files that are treated as a module by css-loader, because this syntax is part of a css module proposal.
You can...
either use the default behavior of css-loader and trigger that behavior via filename: e.g. foostyle.module.scss
or you can configure css-loader to treat all files as modules e.g. loader: 'css-loader', options: { modules: true }
A blogpost with an example can be found here: https://til.hashrocket.com/posts/sxbrscjuqu-share-scss-variables-with-javascript
(Be aware that the blogpost doesn't mention the fact that css modules must be used.)
$white-color: #fcf5ed;
:export {
whitecolor: $white-color;
}
and
import variables from 'variables.module.scss';
console.log(variables.whitecolor)
your webpack.config.js will probably contain a chain of loaders with css-loader as last or second-to-last (process-chronologically speaking) and this should work.
module: {
rules: [
{
test: /\.scss$/,
use: [ 'style-loader', 'css-loader', 'sass-loader' ],
},
I would say try using like this
const App = () => {
const [parameters, setParameters] = useState({
fontFamily: ''
});
return (
<div style={setParameters(fontFamily && { fontType: 'font_name' })}>
{content}
</div>
);
};
Hope this works for you.

"Module parse failed: Unexpected token" when added the class field

Below TypeScript code (it means that static class fields and other TypeScript features are available) successfully has been built with Webpack:
export default class ConfigRepresentative {
constructor() {
console.log('ok');
}
}
Fails (same if to remove private and static):
export default class ConfigRepresentative {
private static ownInstanceHasBeenCreated: boolean = false;
constructor() {
console.log('ok');
}
}
Error:
ERROR in ./TypeScriptSource/index.ts 7:10
Module parse failed: Unexpected token (7:10)
You may need an appropriate loader to handle this file type.
| export default class ConfigRepresentative {
|
> private static ownInstanceHasBeenCreated: boolean = false;
|
| constructor() {
webpack.config.js
module.exports = {
entry: './TypeScriptSource/index.ts',
output: {
filename: 'index.js',
path: __dirname,
libraryTarget: 'umd'
},
target: 'node',
mode: 'production',
watch: true,
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts', '.js']
}
};
For saving your time on reproducing this problem, I attached the souse files.
error.zip
It is because the project was inside node_modules folder. The setting exclude: /node_modules/ cancels the rule {test: /\.ts?$/, use: 'ts-loader'}, but without class property code is pure JavaScript.
(I know that it is bad practice - to develop something inside node_modules, however I don't know the other solution for developing dependencies. In this case, single ConfigRepresentative is useless if it does not used by other project).

#ngtools/webpack: missing app.module.ngfactory

I am trying to use the #ngtools/webpack plugin to create an AoT version of my Angular 4 app within webpack 2, but I am having difficulty understanding what this plugin produces.
In particular, I have a main.aot.ts entry point in my webpack for AoT, which looks like this:
// main.aot.ts
import { platformBrowser } from '#angular/platform-browser';
import { AppModuleNgFactory } from '../compiled/src/app/app.module.ngfactory';
const platform = platformBrowser();
platform.bootstrapModuleFactory(AppModuleNgFactory);
and an extract of my webpack.config.js looks like this:
if (envOptions.MODE === 'prod') {
config.module.rules.push(
{test: /\.ts$/, loader: '#ngtools/webpack'}
);
config.plugins.push(
new AotPlugin({
tsConfigPath: path.resolve(__dirname, './app/tsconfig.json'),
entryModule: path.resolve(__dirname, './app/src/app.module#AppModule')
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
mangle: {
screw_ie8: true,
keep_fnames: true
},
compress: {
warnings: false,
screw_ie8: true
},
comments: false
})
);
}
Does this #ngtools/webpack plugin generate module files in the same way that the ngc compiler does, for inclusion in main.aot.ts? If not, how does it work? There aren't many examples of this on the web.
The thing about #ngtools/webpack is that it creates those .ngfactory files in memory. Therefore there is no need to have any main.aot.ts.
main.ts:
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { enableProdMode } from '#angular/core';
import { AppModule } from './app.module';
if (process.env.ENV === 'production') {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);
In your webpack config:
var aotPlugin = new ngToolsWebpack.AotPlugin({
tsConfigPath: helpers.root('tsconfig.json'),
entryModule: helpers.root('app', 'app.module#AppModule')
});
module: {
rules: [
{
test: /\.ts$/,
use: '#ngtools/webpack'
}
]
},
plugins: [
aotPlugin
]
Now, when you run the webpack the #ngtools/webpack will internally compile the Angular out of the box.
It's worth noting it's a good practice to have #ngtools/webpack only for production build because error messages it produces are bollocks.

Cannot find module "./map.jsx"

Whilst developing using react / webpack / node I reference other components using "import Map from './map.jsx';" or similar statements. I then webpacked to a bundle and attempted to host it on IIS along with an index.html page and the fonts folder. However in the console I get the error: Cannot find module "./map.jsx", as if it's trying to reference a local file, but I thought it was supposed to pack those into the bundle?
If there's anything else I can supply to assist troubleshooting, please let me know.
Here's my map.jsx
import React from 'react';
import 'leaflet';
export default class Map extends React.Component {
componentDidMount() {
this.map = new L.Map('map', {
center: new L.LatLng(53.15, 0.54),
zoom: 8,
layers: L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
})
});
this.layersControl = L.control.layers().addTo(this.map);
}
render() {
return (
<div id="map-container" className="pure-u-1">
<div id="map"></div>
</div>
);
}
}
and my app.jsx
import React from 'react';
import Nav from './nav/nav.jsx';
import NavButton from './nav/navbutton.jsx';
import Map from './map.jsx';
export default class App extends React.Component {
render() {
return (
<div className="pure-g">
<Nav>
<NavButton>Test</NavButton>
</Nav>
<Map />
</div>
);
}
}
as well as the webpack.config.js
module.exports = {
entry: "./src/index.jsx",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.png$/, loader: "url-loader", query: { mimetype: "image/png" } },
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader?name=fonts/[name].[ext]"
}
]
}
};

Resources