Webpack bundled packages can't find peer dependencies in vite_rails project - reactjs

I have a rails project that I'm migrating from webpacker to vite.js and a number of my private packages, bundled with webpack all are built with react and so the rails project was setup with webpack and installed react/-dom itself for use in these installed packages.
In the webpacker config I had to setup aliases for most of these so they could find React and React Dom.
const { resolve } = require('path');
module.exports = {
React: resolve(__dirname, '../../node_modules/react'),
ReactDOM: resolve(__dirname, '../../node_modules/react-dom'),
"react": resolve(__dirname, '../../node_modules/react'),
"react-dom": resolve(__dirname, '../../node_modules/react-dom'),
AsyncStorage: resolve(__dirname, '../../node_modules/#react-native-community/async-storage'),
Pusher: resolve(__dirname, '../../node_modules/pusher-js')
}
But I can't find in the vite.js or rollup.js documentation where or even if I have to do something similar. This section of vite's docs makes me think that it's supposed to just be handling it magically but appears to not be.
Here's an example of the error I'm getting:
✘ [ERROR] Could not resolve "ReactDOM"
node_modules/skarsnik/bundled/plugin.js:1:107:
1 │ ...of exports&&"object"==typeof module?module.exports=e(require("React"),require("ReactDOM"),require("GobblaPackage")):"function"==typeof define&&define.amd?define(["Re...
╵ ~~~~~~~~~~
You can mark the path "ReactDOM" as external to exclude it from the bundle, which will remove this
error. You can also surround this "require" call with a try/catch block to handle this failure at
run-time instead of bundle-time.
Any ideas would be greatly appreciated
EDIT
also looking at one of the webpack bundled packages I have externals config which may explain the "Could not resolve 'ReactDOM'":
externals: {
'react': "React",
'react-dom': 'ReactDOM',
'#realgeeks/gobbla/bundled/plugin': "GobblaPackage",
"#react-native-community/async-storage": "AsyncStorage"
}

Related

Vite, NPM, React Component Library Invalid hook call, externals problem?

I was able to bundle my React Component library in Rollup, but I wanted the features of Vite for development and installed in over the weekend. My problem is that now I'm getting the following error when I try to npm link my vite generated distribution with another react probject.
Basically it's saying that it can't use useContext when it gets the 'Provider" which is really just a react context. It seems like it's having a problem here in the bundle when it tries to load it:
var Context=/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);
My vite config looks as such:
export default defineConfig({
plugins: [react(), dts({ insertTypesEntry: true })],
build: {
lib: {
entry: path.resolve(__dirname, "src/lib/index.ts"),
name: "MyLib",
formats: ["umd", "es"],
fileName: (format) => `my-lib.${format}.js`,
},
rollupOptions: {
external: [ "react", "react-dom" ]
}
},
});
Searching said that it might be a problem with my dependencies, using two versions of react or react-dom. I've tried it with every dependency configuration I can think of and it all breaks in different ways. I think maybe npm cacheing could be confusing me or something though.
Have any ideas? Vite works fine in 'dev' mode, and the components were working ok in Rollup so I feel like it's just a dumb configuration thing I don't understand

Netlify - Gatsby alias imports not working

I am getting this error on Netlify build logs:
2:24:32 AM: error Generating JavaScript bundles failed
2:24:32 AM: Can't resolve '#layout/PageContainer' in '/opt/build/repo/src/pages/how-it-works'
2:24:32 AM: If you're trying to use a package make sure that '#layout/PageContainer' is installed. If you're trying to use a local file make sure that the path is correct.
2:24:32 AM: error Generating JavaScript bundles failed
2:24:32 AM: Can't resolve '#pages/HowItWorks' in '/opt/build/repo/src/pages/how-it-works'
2:24:32 AM: If you're trying to use a package make sure that '#pages/HowItWorks' is installed. If you're trying to use a local file make sure that the path is correct.
I have setup webpack alias like so:
// gatsby-node.js
exports.onCreateWebpackConfig = ({ stage, actions }) => {
actions.setWebpackConfig({
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
alias: {
"#pages": path.resolve(__dirname, "src/components/pages/"),
"#layout": path.resolve(__dirname, "src/components/layout/"),
},
extensions: [".js", ".json", ".jsx", ".tsx", ".ts"]
}
});
};
#pages file structure looks like: src -> components -> pages
#layout file structure looks like: src -> components -> layout
I am able to yarn build my repo locally. No issues.
Once I try to deploy/build with Netlify, I get this issue with alias. Why does this not work with Netlify specifically?
I finally got it working, but why it works, I have no clue!!
From what I found out from spending way too much time on this and trying 100 different things.. Ubuntu file systems behave very different from Macs/Windows which is why I was able to build locally with no issues (I'm using Windows). Netlify only uses Ubuntu image to build, so there was no options of using something else.
It's similar to what was mentioned here: https://github.com/gatsbyjs/gatsby/issues/2897
This is what I did to solve my issues:
Rename affected directories:
FROM:
src/components/layout
src/components/pages
TO:
src/components/Layout
src/components/Pages
And then I changed my alias's accordingly:
"#Pages": path.resolve(__dirname, "src/components/Pages")
"#Layout": path.resolve(__dirname, "src/components/Layout")
After this I committed my changes to git and ran a new build on Netlify... and like magic it worked!

Upgrade to Webpack 5 breaking Storybook 5

In process of upgrading a webpack 4/storybook 5 project to webpack 5 to hopefully take advantage of federated modules. I have regular webpack --config webpack.config.js building working atfer some struggle, but I can't seem to overcome this storybook config issue to get that working. there's not a lot in the storybook webpack.config.js - just some module rules for testing for less files and using the appropriate loaders. It seems the error I'm encountering is typical when upgrading webpack majors, as I've found a number of folks that encountered the same thing going from 3-4, but anything I've tried has failed so far. The specific stacktrace is:
Cannot read property 'tapAsync' of undefined
at ExternalModuleFactoryPlugin.apply (/Users/tbullard/Workspace/unify/node_modules/webpack/lib/ExternalModuleFactoryPlugin.js:29:39)
at compiler.hooks.compile.tap (/Users/tbullard/Workspace/unify/node_modules/webpack/lib/ExternalsPlugin.js:24:63)
at SyncHook.eval [as call] (eval at create (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
at SyncHook.lazyCompileHook (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/Hook.js:154:20)
at hooks.beforeCompile.callAsync.err (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/webpack/lib/Compiler.js:665:23)
at _err0 (eval at create (/Users/tbullard/Workspace/unify/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:11:1)
at compiler.inputFileSystem.readFile (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/webpack/lib/DllReferencePlugin.js:72:15)
at process.nextTick (/Users/tbullard/Workspace/unify/node_modules/#storybook/core/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:85:15)
at process._tickCallback (internal/process/next_tick.js:61:11)
Leads me to believe there's a plugin incompatibility 🤷🏻‍♂️ TIA!
As of 6.2.0, Storybook's preview builder is officially Webpack 5 compatible and the manager builder is unofficially Webpack 5 compatible. See this explanation of the builders and Webpack 5 compatibility. Also check out this gist/comments section with more detailed installation instructions.
If I understand correctly, setting the builder to Webpack 5 (as per these instructions) will force the preview builder to use Webpack 5, allowing you to expose your UI components for cool, new Webpack 5 features such as module federation.
However, if you also want to force the manager builder to use Webpack 5 (so that you can just finish breaking up with Webpack 4), you'll need to make use of Yarn selective dependency resolutions. Here is what I did specifically (in a package.json):
"resolutions": {
"webpack": "^5.27.2",
"css-loader": "^5.0.1",
"dotenv-webpack": "^7.0.2",
"html-webpack-plugin": "^5.0.0",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "^5.1.1",
"webpack-dev-middleware": "^4.1.0",
"webpack-virtual-modules": "^0.4.2"
}
With these resolutions, Yarn detects that Webpack 4 is no longer used and removes it. The SB build gives this warning:
info #storybook/react v6.2.0-rc.10
info
info => Loading presets
WARN Unexpected webpack version in manager-builder
WARN - Received: 5.27.2
WARN - Expected: 4.x
One of the tasks of migrating from Webpack 4 to 5 involves manually providing browser polyfills for node packages which were automatically provided by Webpack 4. I want to note that if you find yourself manually providing a ton of polyfills while upgrading Storybook to Webpack 5, you have probably gotten off in the wrong direction. The Storybook dev-server builds get cached in a local (to the package where Storybook is installed) node_modules directory (whatever-package/node_modules/.cache/storybook/dev-server). Deleting the dev-server sub-directory regularly can help you debug your build and potentially spare you from building out long lists of unnecessary node polyfills. (I learned this the hard way).
With that said, for a cleanish install of Storybook you might not actually need any polyfills. On the other hand, some cases do require the node polyfills (e.g. #storybook/addon-docs requires "assert" (see below)). Here is one way to add polyfills (and addons, if you want) to Storybook's Webpack config in main.js:
module.exports = {
core: {
builder: 'webpack5',
},
stories: ['../whatever/src/**/*.stories.#(ts|tsx)'],
addons: [
'#storybook/addon-actions',
'#storybook/addon-controls',
'#storybook/addon-docs',
],
webpackFinal: (config) => {
return {
...config,
resolve: {
...config.resolve,
fallback: {
...config.fallback,
assert: require.resolve('assert-browserify/'),
},
},
};
},
};
Re: addons, I had serious issues with node polyfills when attempting to use addon-essentials. I've been... adding... addons piecemeal instead (standalone packages via npm), and that seems to be working without any polyfills (#storybook/actions and #storybook/controls are good oob; #storybook/docs requires the assert polyfill (above), #storybook/addons is also working fine with theming in manager.ts---that is:
import { addons } from '#storybook/addons';
import { themes } from '#storybook/theming';
addons.setConfig({
theme: themes.dark,
});
I also want to note that adding sass-loader to Webpack config.module.rules works as expected. Some people were running into problems with some scss preset with Storybook and Webpack 5. Here's the relevant portion of a proper Storybook Webpack config for Sass:
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.(scss)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: function () {
return [require('precss'), require('autoprefixer')];
},
},
},
},
{
loader: require.resolve('sass-loader'),
options: {
// using sass (Dart) instead of node-sass because node-sass (Javascript) cannot resolve Yarn 2's Plug'N'Play synthetic node_modules directory
// Evidently, sass is a bit slower to compile than node-sass, but I think I prefer sass anyway for latest features (such as #use)
implementation: require('sass'),
},
},
],
},
],
},
Hope that will get you off the ground 🛫
Storybook is not yet ready to work with Webpack 5 but it is on their roadmap for version 7.0.
More context in this GitHub issue.
Upgrading webpack v4 to v5 in storybook v6.
check the below link for detailed explanation.
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#webpack-5
"#storybook/builder-webpack5": "^6.5.15",
"#storybook/manager-webpack5": "^6.5.15",
It happened to me as well, in the end I solved it setting the dependency for storybook webpack5 but using webpack4:
"#storybook/addon-actions": "^6.2.9",
"#storybook/addon-controls": "^6.2.9",
"#storybook/addon-storysource": "^6.2.9",
"#storybook/builder-webpack5": "^6.2.9",
"#storybook/vue": "^6.2.9",
As I read here: https://stackoverflow.com/a/67075112/5384339 I think it's better to wait a bit before using webpack5

create-react-app can't find react in tests when aliased with preact

I have created a project with "create-react-app". I have added preact to the project by ejecting it and using alias in webpack config.
alias: {
'react': 'preact-compat-enzyme',
'react-dom': 'preact-compat-enzyme',
'react-dom/server': 'preact-render-to-string',
'react-addons-test-utils': 'preact-test-utils',
'react-addons-transition-group': 'preact-transition-group'
}
This works in the code and I am able to render the app. But, in tests I am getting the following error
Cannot find module 'react' from 'App.test.js'
Why can't it find the module? Is there something that we have to add to config other than alias?
This took some digging but, I got it working by adding following in in moduleNameMapper package.json.
"moduleNameMapper": {
"^react$": "preact-compat-enzyme",
"^react-dom$": "preact-compat-enzyme",
"^react-dom/server$": "preact-render-to-string",
"^react-addons-test-utils$": "preact-test-utils",
"^react-addons-transition-group$": "preact-transition-group",
},

Syntax Error In IE 11 for this node_moduels

I am getting a syntax error in IE when this component of react is loaded in the webpage. Has anybody got the same problem? This is an inherited package, and a syntax error from node_modules makes no sense?
"use strict";
/* WEBPACK VAR INJECTION */(function(module) {
const colorConvert = __webpack_require__(/*! color-convert */ "./node_modules/color-convert/index.js");
const wrapAnsi16 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${code + offset}m`;
};
const wrapAnsi256 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${38 + offset};5;${code}m`;
};
If you are using newer versions of Node/NPM, check your package.json file -> "browserslist" section.
This is the default "browserslist" created for you if you do not have one defined:
In this case, if you run "npm start" on your LOCAL Environment, Babel will not create Polyfills for IE11 because its not included as a target browser in "development". To get this working, I deleted my node_modules directory completely, ran 'npm install', updated package.json with:
and ran 'npm start.
The reason why this fails is that babel or your other favorite transpiler might ignore node_modules (if that's how its configured), so you need to include it manually because IE does not support arrow function syntax.
First, if you search for wrapAnsi16 or wrapAnsi256 function names online it'll point you to common npm packages, such as: ansi-styles, chalk or color-convert, debug, strip-ansi, etc.
If you are using Webpack you can add the following to your rules:
module: {
rules: [{
exclude: /node_modules\/(?!(color-convert|ansi-styles|strip-ansi|ansi-regex|debug|react-dev-utils|chalk)\/).*/
}]
}
or, easier to read:
module: {
rules: [{
include: [
path.resolve(__dirname, 'node_modules/ansi-styles'),
path.resolve(__dirname, 'node_modules/strip-ansi'),
... other's here...
path.resolve(__dirname, 'src'),
]
}]
}
Hope this helps somebody in the future ;)
TLDR; you don't need this library, just run
npm run build
And it will be excluded from your build.
I have same problem with create-react-app, and I solve it (no). From my discovery, this library should not appear in browser, because it was designed for nodejs environment. Also I found, this library come to me as dependency of jest, and jest is dependency for tests and it come as dependency for react.
So, I run
npm run build
server -s build
And try my application in IE. And it work. So, when you run
npm start
It make file including dev dependencies and other garbage that should not appear in production and in browser at all. When you run
npm run build
It make file only with required project libraries.
I had similar issue #punkbit solution and installing 'react-app-polyfill'
and importing it at the top of the index.js file solved it
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
If it still does not work delete node-modules and reinstall also clear cache in IE.
All the best :)
This problem occurs because your compiled code contains (modern) ES6 syntax whilst IE11 only supports ES5.
A way to fix this is to instruct webpack to specifically compile the mentioned packages into ES5;
module: {
rules: [{
test: /\.(tsx?|js)$/,
include: [
// These dependencies have es6 syntax which ie11 doesn't like.
// Whenever you see a "SyntaxError" that crashes IE11 because of a new lib, add it here.
path.join(__dirname, 'node_modules/react-intl'),
path.join(__dirname, 'node_modules/pkce-challenge'),
path.join(__dirname, 'node_modules/fuse.js')
],
use: [{
loader: 'ts-loader', // Or whatever loader you're using
}]
}]
}
for me this was: fuse.js, pkce-challenge and react-intl.

Resources