How to get Vite environment variables in tailwind.config.cjs file - environment-variables

I can't figure out how I can grab the specific Vite environment variables in the tailwind.config.cjs file.
.env.development
VITE_TAILWIND_PRESET = preset_one
tailwind.config.cjs
/** #type {import('tailwindcss').Config} */
const presetFiles = {
present_one: './src/styles/presets/one.js',
present_two: './src/styles/presets/two.js',
}
console.log(import.meta.env)
console.log(import.meta.env.VITE_TAILWIND_PRESET)
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [
require('#tailwindcss/forms'),
],
}
The above code throws the error:
console.log(import.meta.env): [vite] Internal server error: [postcss] Unexpected token (7:18)
If I change the code to console.log(process.env) I get all the environment variables except the VITE ones that I've added to the .env.development file.
To be clear, there is nothing wrong with the .env.development file. In my vite.config.js file the file is loaded correctly using
import { defineConfig, loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
...

Related

remoteEntry.js not found on Jenkins

We are deploying a remote app written in NextJS and Typescript; The host app is in React only.
Currently the host app gets a 404 not found error as the remote app runs into this error in the Build Snapshot on Jenkins
+ ls ./dist/static/chunks/remoteEntry.js
ls: cannot access './dist/static/chunks/remoteEntry.js': No such file or directory
script returned exit code 2
However, the file is generated locally and both apps are able to spin up in local environment.
Here is our next.config.js:
const NextFederationPlugin = require('#module-federation/nextjs-mf');
const { exposedModules } = require('./lib/routes');
const version = process.env.VERSION_OVERRIDE || require('./package.json').version;
const deps = require('./package.json').dependencies;
// Note: This path needs to match with what's specified in CIRRUS_FRONTEND_ENTRYPOINT for www.
const assetBasePath = process.env.CDN_PATH ? `${process.env.CDN_PATH}${version}` : process.env.ASSET_BASE_PATH;
// Note: Heavily references module federation example meant for omnidirectional federation between Next apps.
// Changes mostly around path resolution due to our current resolution pattern via cdn
// https://github.com/module-federation/module-federation-examples/blob/master/nextjs/home/next.config.js
module.exports = {
webpack(config, options) {
Object.assign(config.experiments, { topLevelAwait: true });
// Integrated mode calls `next build` which has minimization by default. For local development, this is unnecessary.
if (process.env.NEXT_PUBLIC_ENVIRONMENT === 'INTEGRATED') {
config.optimization.minimize = false;
}
if (!options.isServer) {
console.log("Not Server");
config.output.publicPath = 'auto';
config.plugins.push(
new NextFederationPlugin({
name: 'cirrus',
filename: 'static/chunks/remoteEntry.js',
exposes: {
'./FederatedRouter': './lib/FederatedRouter',
...exposedModules
},
remoteType: 'var',
remotes: {},
shared: {
'#transcriptic/amino': {
requiredVersion: deps['#transcriptic/amino'],
singleton: true
},
react: {
requiredVersion: deps.react,
singleton: true
},
'react-dom': {
requiredVersion: deps['react-dom'],
singleton: true
},
'#strateos/micro-apps-utils': {
requiredVersion: deps['#strateos/micro-apps-utils'],
singleton: true
}
},
extraOptions: {
// We need to override the default module sharing behavior of this plugin as that assumes a nextjs host
// and thus next modules will be provided by the parent application.
// However, web is currently NOT a nextjs application so this child application so that assumption is
// invalid. Note that this means we need to ensure we explicitly specify common modules such as `react`
// in the `shared` key above.
skipSharingNextInternals: true
}
})
);
} else {
console.log("Is Server");
}
return config;
},
// Note: Annoyingly, NextJS automatically automatically appends a `_next` directory for assetPrefix
// but NOT public path so we'll have to manually include it here.
publicPath: `${assetBasePath}/_next/`,
// Note: If serving assets via CDN, assetPrefix is required to help resolve static assets.
// Also, NextJS automatically appends and expects a `_next` directory to the assetPrefix path.
// See https://nextjs.org/docs/api-reference/next.config.js/cdn-support-with-asset-prefix
assetPrefix: process.env.CDN_PATH ? assetBasePath : undefined,
distDir: 'dist',
// Use index react-router as fallback for resolving any pages that are not directly specified
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: '/'
}
]
};
}
};
Tried upgrade NextJS from 12.1.6 to 12.2.2
Tried upgrade Webpack from 5.74.0 to 5.75.0
Cleaned cache by sh 'yarn cache clean'
Tried clear env by sh 'env -i PATH=$PATH make build-snapshot'
Hash of node modules by tar -cf - node_modules | md5sum
Downgraded "#module-federation/nextjs-mf" from 5.12.9 to 5.10.5
Verified file writing permission

Error loading appsettings.Production.json due to digest integrity issue

I'm developing a Blazor WebAssembly app with PWA enabled, and with files appsettings.json, appsettings.Development.json and appsettings.Production.json. The last one is empty because it would contain secrets to replace when production environment is deployed to a kubernetes cluster.
I'm using k8s to deploy, and a Secret resource to replace the empty appsettings.Production.json file by an encrypted file, into a nginx based container with the published blazor app inside.
Now I'm getting this issue in the browser:
When the application was built using docker build in a CI pipeline, the file was an empty json file, and got a SHA computed that does not match then one computed by the build process.
My question is: How can I replace the appsettings.Production.json during deployment, much later than the build process, and don't have the integrity test failed over that file?
The file blazor.boot.json does not contain any SHA for the appsetting.Production.json file:
{
"cacheBootResources": true,
"config": [
"appsettings.Development.json",
"appsettings.json",
"appsettings.Production.json"
],
"debugBuild": false,
"entryAssembly": "IrisTenantWeb",
"icuDataMode": 0,
"linkerEnabled": true,
"resources": {
"assembly": {
"Azure.Core.dll": "sha256-rzNx\/GlDpiutVRPzugT82owXvTopmiixMar68xLA6L8=",
// Bunch of .dlls,
"System.Private.CoreLib.dll": "sha256-S7l+o9J9ivjCunMa+Ms\/JO\/kVaXLW8KTAjq1eRjY4EA="
},
"lazyAssembly": null,
"pdb": null,
"runtime": {
"dotnet.timezones.blat": "sha256-SQvzbzBfueaAxSKIKE1khBH02NH2MJJaWDBav\/S5MSs=",
"dotnet.wasm": "sha256-YXYNlLeMqRPFVpY2KSDhleLkNk35d9KvzzwwKAoiftc=",
"icudt.dat": "sha256-m7NyeXyxM+CL04jr9ui1Z6pVfMWwhHusuz5qNZWpAwA=",
"icudt_CJK.dat": "sha256-91bygK5voY9lG5wxP0\/uj7uH5xljF9u7iWnSldT1Z\/g=",
"icudt_EFIGS.dat": "sha256-DPfeOLph83b2rdx40cKxIBcfVZ8abTWAFq+RBQMxGw0=",
"icudt_no_CJK.dat": "sha256-oM7Z6aN9jHmCYqDMCBwFgFAYAGgsH1jLC\/Z6DYeVmmk=",
"dotnet.5.0.5.js": "sha256-Dvb7uXD3+JPPqlsw2duS+FFNQDkFaxhIbSQWSnhODkM="
},
"satelliteResources": null
}
}
But the service-worker-assets.js file DOES contains a SHA computed for it:
self.assetsManifest = {
"assets": [
{
"hash": "sha256-EaNzjsIaBdpWGRyu2Elt6mv3X+48iD9gGaSN8xAm3ao=",
"url": "appsettings.Development.json"
},
{
"hash": "sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=",
"url": "appsettings.json"
},
{
"hash": "sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=",
"url": "appsettings.Production.json"
},
{
"hash": "sha256-OV+CP+ILUqNY7e7\/MGw1L5+Gi7EKCXEYNJVyBjbn44M=",
"url": "css\/app.css"
},
// ...
],
"version": "j39cUu6V"
};
NOTE: You can see that both appsettings.json and appsettings.Production.json have the same hash because they are both the empty json file {}. But in production the second one is having a computed hash of YM2gjmV5... and issuing the error.
I can't have different build processes for different environments, because that would not ensure using the same build from staging and production. I need to use the same docker image but replacing the file at deployment time.
I edited the wwwroot/service-worker.published.js file, which first lines are as follow:
// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations
self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
async function onInstall(event) {
console.info('Service worker: Install');
// Fetch and cache all matching items from the assets manifest
const assetsRequests = self.assetsManifest.assets
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
.map(asset => new Request(asset.url, { integrity: asset.hash }));
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}
...
I added an array of patterns, similar to offlineAssetsInclude and offlineAssetsExclude to indicate which files I want to skip integrity checks.
...
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
const integrityExclude = [ /^appsettings\.Production\.json$/ ]; // <-- new variable
Then at onInstall, instead of always returning a Request with integrity set, I skipped it for excluded patterns:
...
async function onInstall(event) {
console.info('Service worker: Install');
// Fetch and cache all matching items from the assets manifest
const assetsRequests = self.assetsManifest.assets
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
.map(asset => {
// Start of new code
const integrity =
integrityExclude.some(pattern => pattern.test(asset.url))
? null
: asset.hash;
return !!integrity
? new Request(asset.url, { integrity })
: new Request(asset.url);
// End of new code
});
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}
...
I'll wait for others to comment and propose other solutions, because the ideal response would set the correct SHA hash to the file, instead of ignoring it.

Using <style lang="scss"> in vue component gives error

I am trying to use vue js in rails.
Everything works, except when I tried to use <style> inside .vue component
The exact error is:
./app/javascript/layouts/dashboard.vue?vue&type=style&index=0&lang=scss& (./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/dist/cjs.js??ref--1-2!./node_modules/style-loader/dist!./node_modules/css-loader/dist/cjs.js??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/sass-loader/dist/cjs.js??ref--5-3!./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/layouts/dashboard.vue?vue&type=style&index=0&lang=scss&)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Expected newline.
My environment.js file
const { environment } = require('#rails/webpacker')
const { VueLoaderPlugin } = require('vue-loader')
const vueLoader = require('./loaders/vueLoader')
const vuetifyLoader = require('./loaders/vuetifyLoader')
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('vue', vueLoader)
environment.loaders.prepend('vuetify', vuetifyLoader)
const resolver = {
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
environment.config.merge(resolver)
module.exports = environment
VuetifyLoader.js file
module.exports = {
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader#^7.0.0
options: {
implementation: require('sass'),
fiber: require('fibers'),
indentedSyntax: true // optional
},
// Requires sass-loader#^8.0.0
options: {
implementation: require('sass'),
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true // optional
},
},
},
],
}
install these two plugins.
npm install --save node-sass
npm install --save sass-loader
So, the problem was with fiber and indentedSyntax. After removing those two, everything works as expected. I was getting lots of error related to scss like
like
expected new line
in sass files inside node_modules. I don't know, why vuetify recommends to use fiber in sass loader.

How to configure webpack devServer port?

I'm trying to use webpack in my Symfony app in docker, but I'm still getting error:
GET http://localhost:8000/sockjs-node/info?t=1556798329924 404 (Not Found)
Everything works fine axcepts this error...
App is running on port 8000 and node on port 8081. The address with 8081 port is accessible, but how can I tell webpack to use port 8081 with devServer?
Here is my webpack.config.js:
const Encore = require('#symfony/webpack-encore');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const outputPath = './public/build/';
const publicPath = '/build';
Encore
.setOutputPath(outputPath)
.setPublicPath(publicPath)
// Clean output dir before build
.cleanupOutputBeforeBuild()
.splitEntryChunks()
.enableSingleRuntimeChunk()
// uncomment if you're having problems with a jQuery plugin
.autoProvidejQuery()
// Generate JS files
.addEntry('loader', './assets/javascript/loader.js')
.addEntry('admin-loader', './assets/javascript/admin.js')
// Generate CSS files
.addStyleEntry('forms', './assets/styles/forms.scss')
.addStyleEntry('grid', './assets/styles/grid.scss')
.addStyleEntry('reboot', './assets/styles/reboot.scss')
.addStyleEntry('styles', './assets/styles/styles.scss')
.addStyleEntry('utilities', './assets/styles/utilities.scss')
.addStyleEntry('admin', './assets/styles/admin.scss')
.enableEslintLoader()
.configureTerserPlugin((options) => {
options.cache = true;
options.parallel = true;
options.terserOptions = {
output: {
comments: false,
}
}
})
.configureSplitChunks((options) => {
options.chunks = 'all',
options.maxInitialRequests = Infinity,
options.cacheGroups = {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `pckg.${packageName.replace('#', '')}`;
},
}
}
})
// Enable SASS loader with PostCSS config
.enableSassLoader()
.enablePostCssLoader()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
// CSS Hot Loader for HMR in webpack dev server
.addLoader({
enforce: 'post',
test: /\.(s?c|sa)ss$/,
exclude: /node_modules/,
loader: 'css-hot-loader',
})
.addPlugin(new StyleLintPlugin({
lintDirtyModulesOnly: Encore.isProduction(),
context: './assets/styles/',
quiet: false,
}));
const config = Encore.getWebpackConfig();
// Export settings and generate files
module.exports = config;
Does anyone know?

How to handle global when format is 'es'?

I have identified an Javascript library (incremental-dom) as both a global and external. I'm loading the library in a script tag.
When the rollup format is 'iife' the library in injected into the iife and everything works.
However when I use the 'es' format, the global is never referenced and the browser throws a type error:
Uncaught TypeError: Failed to resolve module specifier 'incremental-dom'
Here's my rollup.config.js file:
const path = require('path');
const root = process.cwd();
const string = require('rollup-plugin-string');
const superviews = require('rollup-plugin-superviews');
export default [
{
input: path.resolve(root, 'src', 'idx-admin-tab', 'component.js'),
plugins: [
superviews({include: 'src/**/*.html'}),
string({include: ['src/**/*.css', 'src/**/*.svg']})
],
globals: {'incremental-dom': 'IncrementalDOM'},
external: ['incremental-dom'],
output: {
file: path.resolve(root, 'dist', 'idx-admin-tab.es.js'),
format: 'es'
}
}
];
globals only works in the context of iife or umd output — if you're creating an es bundle, it will simply be ignored.
If you wanted to just use the browser's native import support, you would have to turn the module specifier incremental-dom into one that the browser can resolve — something like this:
export default [
{
// ...
external: ['incremental-dom'],
paths: {
'incremental-dom': '/node_modules/incremental-dom/dist/incremental-dom.js'
},
// ...
}
];
Unfortunately incremental-dom doesn't have an ESM build, so you can't import it. So if you don't want to bundle it, you will have to trick Rollup into using the global IncrementalDOM even in es mode.
You should be able to do that with rollup-plugin-virtual:
export default [
{
// ...
plugins: [
superviews({include: 'src/**/*.html'}),
string({include: ['src/**/*.css', 'src/**/*.svg']}),
virtual({
'incremental-dom': 'export default window.IncrementalDOM'
})
],
// ...
}
];

Resources