How to use vite to build esm to commonjs without excluding node modules like stream and path? - node.js

I want to use vite to pack my esm js to commonjs, but it will clear node modules.
vite.config.js
import { defineConfig } from 'vite';
const config = defineConfig({
envDir: process.cwd(),
build: {
lib: {
entry: 'index.js',
formats: ['cjs']
},
rollupOptions: {
output: {
entryFileNames: '[name].cjs'
}
},
emptyOutDir: true
}
});
export default config;
My example index.js
import Stream from 'node:stream';
console.log(`✨`, `Stream`, Stream);
When builded the stream will be an empty object.
How can I prevent node modules from being cleaned up?

I had a similar issue and solved it by specifying:
build: { ssr: true }
Then to eliminate the warning, you should also specify:
rollupOptions: {
input: 'index.js'
}

Related

Using node polyfills in a es module that is imported into angular: Buffer is not defined

I want to create an ES module which can be easily imported in a frontend environment (in my test case angular). However I have a commonjs module in my dependencies which uses some node functionalities. At the current state my module is only usable if there are some polyfills defined within angular (I found them here: global, buffer, process ):
// in polyfills.ts
(window as any).global = window;
global.Buffer = global.Buffer || require("buffer").Buffer;
import * as process from "process";
window["process"] = process;
My goal is to build my module in a way that nothing needs to be done on the frontend side except installing the package. For this I want to move the polyfill part down a level to my module.
To reach this goal I am trying to bundle my module using webpack and defining the polyfills there. This is my current config:
import path from "path";
import { fileURLToPath } from "url";
import { createRequire } from "module";
import webpack from "webpack";
const require = createRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default {
entry: "./src/index.ts",
module: {
rules: [
{
test: /\.ts?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
}),
],
resolve: {
fallback: {
buffer: require.resolve("buffer"),
process: require.resolve("process"),
},
extensionAlias: {
".js": [".ts", ".js"],
".mjs": [".mts", ".mjs"],
},
},
experiments: {
outputModule: true,
},
output: {
path: path.resolve(__dirname, "dist"),
library: {
type: "module",
},
},
};
Webpack runs this config without errors (only with size related warnings) but when I include the bundle into angular and remove the buffer polyfill there I still get the runtime error Buffer is not defined (chrome).
Is this a minor error in my config or did I miss something
important which makes my whole approach unreasonable?

Can we enable cssAddon in Quasar with Vite plugin installation?

I have a Laravel 9 application using Vite, VueJS 3, InertiaJS and Quasar. I installed Quasar with the Vite Plugin Doc here. Now my problem is that I want to use the Flex Addons to have responsive margin/padding Flex addon, but in the documentation it is written that it needs to be enabled through quasar.config.js > framework > cssAddon: true , but I don't have a quasar.config.js file. I only have a vite.config.js file and my app.js root file where I load Quasar.
So is there an other way to enable cssAddon with vite plugin ? And is there an other way to have responsive margin without enabling cssAddon ?
Thanks for your help :)
This is my app.js file
import './bootstrap';
import { createApp, h } from 'vue';
import { Quasar } from 'quasar';
import quasarLang from 'quasar/lang/fr';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers';
import '#quasar/extras/material-icons/material-icons.css'
import 'quasar/src/css/index.sass'
import AppLayout from './Layouts/AppLayout.vue';
createInertiaApp({
resolve: name => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(Quasar, {
plugins: {},
lang: quasarLang,
})
.mount(el);
}
})
This is my vite.config.js file
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
import { quasar, transformAssetUrls } from '#quasar/vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
//'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {},
},
}),
quasar({
sassVariables: 'resources/sass/quasar-variables.scss',
}),
],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
});
I tried to add cssAddon:true under Quasar in both files but it doesn't work.

`exports` found in bundle when format set to `esm` (using `#rollup/plugin-node-resolve`)

I have nodeResolve set to only resolve svelte (since I only use stores) and string-argv
// rollup.config.js
import { nodeResolve } from '#rollup/plugin-node-resolve'
import { defineConfig } from 'rollup'
const config = defineConfig({
input: 'main.js',
output: {
file: 'bundle.js',
format: "esm"
},
plugins: [nodeResolve({
preferBuiltins: true,
resolveOnly: ['svelte', 'string-argv']
})],
external: ['cac', 'colors'],
})
export default config
but for some reason references to exports is included in my bundle and importing the module doesn't work. How do i fix this?
EDIT: i checked the string-argv code in node_modules and all the references to exports is in that module.

vite dev server execute middleware before all other middleware

With vue-cli it was possible to configure webpack devServer.before function like this:
devServer: {
before(app) {
app.get('/apiUrl', (req, res) => res.send(process.env.API_URL))
}
},
How is it possible to configure Vite dev server to obtain the same behavior?
(I tried with the proxy option but it does not work.)
According to this github issue, environment variables are not accessible in file vite.config.js (neither in vite.config.ts). However, the discussion in this issue also mentions a workaround that you can use in this file:
import { defineConfig, loadEnv } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig(({mode}) => {
const env = loadEnv(mode, process.cwd());
return {
plugins: [
vue(),
],
server: {
proxy: {
'^/apiUrl': {
target: env.VITE_API_TARGET,
changeOrigin: true,
}
}
},
}
})
Note that the variable name must start with VITE_ for this to work.

I am trying to use react-app-rewired for changing file-loader config

I'm using react-app-rewired to change the webpack config. My intention is to be able to load GLTF files into react for threejs.
I found an example using the npm package. https://www.npmjs.com/package/gltf-webpack-loader. I have tried the following code but I getting an error with my webpack. The following code is my config-overrides.js
module.exports = function override(config, env) {
config.module.rules.push({
test: /\.(gltf)$/,
use: [
{
loader: "gltf-webpack-loader"
}
]
});
config = { ...config, {
test: /\.(bin)$/,
use: [
{
loader: "file-loader",
options: {}
}
]
}
};
return config;
};
I want to be able to load GLTF files into a react application.

Resources