I have external directory common and I would like to import react components from that directory into web-static. In web-static I am using nextjs.
Currently I having this error:
Module not found: Can't resolve 'react' in '/Users/jakub/Sites/WORK/wilio-web-common/common/src/#vendor/atoms'
I added these lines to next.config.js:
const babeRule = config.module.rules[babelRuleIndex];
if (babeRule && babeRule.test) {
babeRule.test = /\.(web\.)?(tsx|ts|js|mjs|jsx)$/;
if (babeRule.include) {
babeRule.include = [
...babeRule.include,
resolve(__dirname, "../common/src/#vendor"),
];
}
}
config.resolve.alias = {
...config.resolve.alias,
"#vendor": resolve(__dirname, "../common/src/#vendor")
};
My tsconfig.json file:
"paths": {
"#vendor/*": ["../common/src/#vendor/*"]
}
Webpack can resolve these components but can't resolve installed packages in these components.
../common/src/#vendor/atoms/Test.js
Module not found: Can't resolve 'react' in '/Users/user1/Sites/WORK/web-app/common/src/#vendor/atoms'
Do I need to include this directory also in webpacks config.externals? Current nextjs webpack externals
-----
options.isServer: false
[ 'next' ]
-----
-----
options.isServer: true
[ [Function] ]
-----
How can be this done? Thanks for any help
Starting in Next.js 10.1.2, you can use the currently experimental externalDir option in next.config.js:
module.exports = {
experimental: {
externalDir: true,
},
};
Note that for React components to work, I also had to declare the root package.json as a yarn workspace:
{
// ...
"private": true,
"workspaces": ["next-js-directory"],
// ...
}
Related
It seems that vite does not do automatic polyfills anymore - vite 4.0.0
How do you guys go about this? I have tried multiple variations of what I could find over the internet and none of them seems to be solid.
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
Build failed with 2 errors:
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
my config
// yarn add --dev #esbuild-plugins/node-globals-polyfill
import { NodeGlobalsPolyfillPlugin } from "#esbuild-plugins/node-globals-polyfill";
// yarn add --dev #esbuild-plugins/node-modules-polyfill
import { NodeModulesPolyfillPlugin } from "#esbuild-plugins/node-modules-polyfill";
// You don't need to add this to deps, it's included by #esbuild-plugins/node-modules-polyfill
import rollupNodePolyFill from "rollup-plugin-node-polyfills";
export default {
resolve: {
alias: {
// This Rollup aliases are extracted from #esbuild-plugins/node-modules-polyfill,
// see https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/polyfills.ts
// process and buffer are excluded because already managed
// by node-globals-polyfill
util: "rollup-plugin-node-polyfills/polyfills/util",
sys: "util",
events: "rollup-plugin-node-polyfills/polyfills/events",
stream: "rollup-plugin-node-polyfills/polyfills/stream",
path: "rollup-plugin-node-polyfills/polyfills/path",
querystring: "rollup-plugin-node-polyfills/polyfills/qs",
punycode: "rollup-plugin-node-polyfills/polyfills/punycode",
url: "rollup-plugin-node-polyfills/polyfills/url",
string_decoder: "rollup-plugin-node-polyfills/polyfills/string-decoder",
http: "rollup-plugin-node-polyfills/polyfills/http",
https: "rollup-plugin-node-polyfills/polyfills/http",
os: "rollup-plugin-node-polyfills/polyfills/os",
assert: "rollup-plugin-node-polyfills/polyfills/assert",
constants: "rollup-plugin-node-polyfills/polyfills/constants",
_stream_duplex: "rollup-plugin-node-polyfills/polyfills/readable-stream/duplex",
_stream_passthrough: "rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough",
_stream_readable: "rollup-plugin-node-polyfills/polyfills/readable-stream/readable",
_stream_writable: "rollup-plugin-node-polyfills/polyfills/readable-stream/writable",
_stream_transform: "rollup-plugin-node-polyfills/polyfills/readable-stream/transform",
timers: "rollup-plugin-node-polyfills/polyfills/timers",
console: "rollup-plugin-node-polyfills/polyfills/console",
vm: "rollup-plugin-node-polyfills/polyfills/vm",
zlib: "rollup-plugin-node-polyfills/polyfills/zlib",
tty: "rollup-plugin-node-polyfills/polyfills/tty",
domain: "rollup-plugin-node-polyfills/polyfills/domain",
},
},
optimizeDeps: {
esbuildOptions: {
// Node.js global to browser globalThis
define: {
global: "globalThis",
},
// Enable esbuild polyfill plugins
plugins: [
NodeGlobalsPolyfillPlugin({
process: true,
buffer: true,
}),
NodeModulesPolyfillPlugin(),
],
},
},
build: {
rollupOptions: {
plugins: [
// Enable rollup polyfills plugin
// used during production bundling
rollupNodePolyFill(),
],
},
},
};
I encountered the same issue "cannot be marked as external" when working with the bip39 package and getting error because of buffer not defined. I tried many stuffs so not sure how what I solved, but here is my configuration (working with svelteKit):
In vite.config.js:
import { sveltekit } from '#sveltejs/kit/vite';
import type { UserConfig } from 'vite';
const config: UserConfig = {
plugins: [sveltekit()],
resolve: {
alias: {
// polyfills
Buffer: 'vite-compatible-readable-buffer',
stream: 'vite-compatible-readable-stream',
util: 'rollup-plugin-node-polyfills/polyfills/util',
}
}
};
export default config;
In layout.ts:
import { Buffer as BufferPolyfill } from 'buffer'
declare var Buffer: typeof BufferPolyfill;
globalThis.Buffer = BufferPolyfill
In app.html:
<script>
/**
* this is a hack for error: global is not defined
*/
var global = global || window
</script>
I hope it helps. I'm new to svelte and I don't 100% know what I'm doing :p
I have upgraded from Vite 2.9.13 to 4.0.4, and to be on theme with the version number Vite can not find the entry point for JS anymore. It emits everything correctly except the JavaScript bundle which ends up like below. No error messages or anything.
// main-12345678.js
import "./reset-12345678.js";
const customfonts = "";
const style = "";
//# sourceMappingURL=main-12345678.js.map
// Where is the rest of my bundle? ¯\_(ツ)_/¯
Any ideas as to why I get a blank page and the almost empty JS bundle above?
vite --mode staging --config vite.config.js build
// vite.config.js
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
export default defineConfig(({ command, mode }) => ({
plugins: [react()],
root: "client",
build: {
sourcemap: mode !== "production",
minify: mode !== 'production' ? false : 'esbuild',
outDir: "dist/publish",
rollupOptions: {
input: {
main: new URL("./client/index.html", import.meta.url).pathname,
other: new URL("./client/other.html", import.meta.url).pathname,
},
},
},
}));
I have 2 entry points to my app, with vite-config.js setup as follows:
export default defineConfig({
build: {
emptyOutDir: false,
manifest: true,
outDir: 'dist',
rollupOptions: {
input: {
app: '/src/app/app.js',
pub: '/src/app/pub.js'
}
},
commonjsOptions: { include: [] }
},
optimizeDeps: { disabled: false },
plugins: [vue()]
})
This results in 1 manifest.json file, and the corresponding app.css/js/pub.css/js in my dist folder, along with any other assets that my app references like images.
Occasionally, running vite build will result in an extra set of CSS/JS files in my dist folder. This extra file set is a random component or JS file from my codebase or node_modules, and oftentimes will contain a bunch of code that should be in dist/app.js. I'm tearing my hair out trying to figure this out. I've updated from Vite 3 to 4 and tried every adjustment I can find for the config file. Here's an example where InputRadios.vue, a component from my repo, is showing up and contains most of my app code.
[dist]
[assets]
- app.css
- app.js
- InputRadios.js
- InputRadios.css
- logo.svg
- pub.js
- pub.css
If I comment out any references to InputRadios.vue, then e.g. VueRouter.css/js appears in the dist folder. If I comment out VueRouter, some other random file imported somewhere in my codebase shows up.
Should this be working the way I'm expecting, or am I misunderstanding how rollupOptions works?
I don't know why I was getting the above behavior with multiple input entries for rollupOptions, but here's my solution: use multiple vite configs.
vite.config-dev.js:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig({
publicDir: false,
plugins: [vue()],
server: {
port: 3030,
strictPort: true
},
preview: {
port: 8080,
strictPort: true
}
})
vite.config-app.js:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig({
build: {
emptyOutDir: false,
manifest: 'manifest-app.json',
outDir: 'dist',
rollupOptions: {
input: {
app: '/src/app/app.js'
}
}
},
plugins: [vue()]
})
vite.config-pub.js:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig({
build: {
emptyOutDir: false,
manifest: 'manifest-pub.json',
outDir: 'dist',
rollupOptions: {
input: {
pub: '/src/app/pub.js'
}
}
},
plugins: [vue()]
})
package.json:
...
"scripts": {
"dev": "vite -c vite.config-dev.js",
"build": "vite build -c vite.config-app.js && vite build -c vite.config-pub.js",
...
This is running through an Express server that serves some private and some public pages, hence the 2 entry points. If anyone runs into this and needs full(er) code examples, post a comment.
Using Vue 3, how do I add path-browserify to vue.config.js?
module.exports = {
chainWebpack: config => {}
}
I am receiving the following error when compiling:
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
Webpack 5 removed some things that Webpack 4 included in the bundle.
To get it all back in a vue3 app you can use the polyfill plugin.
From a vanilla create-vue-app with babel:
> npm i node-polyfill-webpack-plugin
babel.config.js
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
]
}
vue.config.js
const { defineConfig } = require("#vue/cli-service");
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
optimization: {
splitChunks: {
chunks: "all",
},
},
},
});
With #Zack's help, using chainWebpack:
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
module.exports = {
chainWebpack: config => {
config.plugin('polyfills').use(NodePolyfillPlugin)
},
}
I am getting the following error from webpack.
ERROR in ./wwwroot/js/admin/infrastructure/typeaheadComponent.ts
Module not found: Error: Can't resolve 'typeahead' in ...
I have the following installed
npm install typeahead.js
npm install #types/typeahead
My typescript is as follows, using node module resolution.
import { module } from "angular";
import "typeahead";
// necessary to import typeahead into JQuery, as otherwise
// typeahead below is not defined.
class TypeAheadController {
foo(e) {
$(e).typeahead(...)
}
}
this generates javascript as follows:
"use strict";
var angular_1 = require("angular");
require("typeahead");
var TypeAheadController = (function () { ...
My webpack.config.js is as follows:
module.exports = {
context: __dirname,
entry: [
"./app.ts",
"./tab.ts",
"./client/clientService.ts",
"./client/clientSearchComponent.ts",
"./infrastructure/messageComponent.ts",
"./infrastructure/typeaheadComponent.ts",
"./url.ts"],
output: {
filename: "./wwwroot/js/admin/admin.js"
},
devtool: "source-map",
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
imported into a gulp task.
How do I specify that typeahead is located in node_modules/typeahead.js/dist/typeahead.bundle.js
The module is called typeadhead.js so you also need to import typeahead.js, not typeahead.
import "typeahead.js";
The import is always the same as the name you use to install it with npm. And it's not even special, it simple looks into node_modules and finds the directory with the given name. Then it looks into package.json and imports the file specified in the main field. See also Node.js - Folders as Modules.
You could use resolve.alias to change the name of the import, but there is not really a good reason for doing that in this case.
I resolved this by making the following changes.
You need to import Bloodhound and Typeahead seperately. To do this edit your webpack.config.js
resolve: {
extensions: ['.js', '.ts'],
alias: {
typeahead: 'corejs-typeahead/dist/typeahead.jquery.min.js',
bloodhound: 'corejs-typeahead/dist/bloodhound.min.js'
}
},
And then in your .ts file:
import "typeahead";
import * as Bloodhound from "bloodhound";
You could solve this using aliasing. Minimal example of what to change in your webpack.config.js:
module.exports = {
/* ... everything you currently have */
resolve: {
alias: {
typeahead: 'typeahead.js'
}
}
}