I am just starting to dabble in react and one of the first components I want is something to use photoswipe.js. (react photoswipe) It looks like there is a pretty decent one on npm, but I am running into a problem. When I run my storybook to start testing and building my component, I get an error from babel. It says:
in ./~/react-photoswipe/lib/index.js
Module build failed: ReferenceError: [BABEL] C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\react-photoswipe\lib\index.js: Using removed Babel 5 option: C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\react-photoswipe\.babelrc.stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets
at Logger.error (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\file\logger.js:41:11)
at OptionManager.mergeOptions (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\file\options\option-manager.js:220:20)
at OptionManager.init (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\file\options\option-manager.js:368:12)
at File.initOptions (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\file\index.js:212:65)
at new File (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\file\index.js:135:24)
at Pipeline.transform (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-core\lib\transformation\pipeline.js:46:16)
at transpile (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-loader\lib\index.js:46:20)
at C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-loader\lib\fs-cache.js:79:18
at ReadFileContext.callback (C:\Code\GIT\DanStatenReact\DanStatenUI\node_modules\babel-loader\lib\fs-cache.js:15:14)
at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:365:13)
So I did a bit of poking around and noticed that the babel rc file appears to be set to stage:0 which from my understanding seems like a really bad idea if you are producing a component that is supposed to be durable as the javascript spec updates and evolves.
I am still pretty new to using babel though so I am kind of having a hard time tracking down what I would need to update for this component to get it working in my environment with the newer babel. Has anyone encountered this problem with this component before? Does anyone have any advice or tips on how to troubleshoot the bable transpile and track down what I need to update?
The .babelrc from react-photoswipe does not work with babel 6. But it doesn't need to, because main entry point of the module is lib/index.js, which contains the already transpiled code. You're trying to transpile it again, and it automatically applies the .babelrc closest to it.
You should exclude node_modules in your webpack config, for example:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
It will not only fix your issue, but also reduce the build time.
Thanks Michael for getting me pointed in the right direction. I am testing and building a component using a react storybook tool that has a whitelist configuration that tells it what node modules not to run through the full build. I had to add react-photoswipe to that whitelist and it is now working... well starting to work, but this problem is taken care of.
Related
I am new to Electron, and I have been having some trouble trying to do something simple in an Electron + React application. All I want to do is: Load a 3D model (.glb) located in my src/assets directory from a React component. I created the project using this guide. In a typical React project, I can just import the file directly in my JS module and reference the path in my code. However, with the default Webpack config, the file can't be found. There's obviously a gap in my understanding on how React + Webpack work when loading assets. What am I missing? Any help is greatly appreciated.
Thanks!
Turns out, the Webpack documentation spells out the answer clearly. Who knew? I found a lot of similar questions/answers for older versions of Webpack, so I'll post one here for Webpack 5. It requires a trivial two-line addition to the webpack.rules.js file:
{
test: /\.(png|jpg|gif|svg|glb)$/,
type: 'asset/resource'
}
The key is the asset/resource line. It's new to Webpack 5 and allows the bundling of assets without needing any additional loaders. With that, assets can be included as Javascript modules and Webpack will take care of the rest.
So, one can do:
import modelSrc from "../assets/some_awesome_model.glb";
And that's that. Webpack will spit out a URL such as /9feee593dc369764dd8c.glb, meaning Webpack has located and processed the asset.
I’m building an app which uses React(v.17.0), Next.js(v11.1.2), … and other stacks.
Next.js probably, in default, supports IE11.
After I added some packages to my project, it fails on IE11. It says, in console, spread operator is not supported and some other stuff.
I guess the reason is packages which occur problems doesn’t properly set up. For example, packages are built in typescript but they don’t specify tsconfig.compilerOptions.target to es5. I looked it up the source.
I have tried
Adding react-app-polyfill/ie11 in pages/_app.js
Should I try…
Contribute each packages so that it can be compatible with IE11.
Webpack or babel setting: I’ve never done custom webpack or babel settings before. I always go with the default settings. I haven’t tried this because I know webpack and babel affects project source but not sure it ALSO affects dependent packages.
As you mentioned, the spread operator does not work correctly in IE. This is because it is part of ES6 and IE does not support this feature. You can view the browser compatibility table from this doc:Spread syntax (...)-Browser compatibility.
So you may need to convert it to ES5, usually you can use transpilers like Babel, simple configuration example:
{
test: /\.js$/, //Regular expression
exclude: /(node_modules|bower_components)/,//excluded node_modules
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"] //Preset used for env setup
}
}
}
Another option is to define your own function according to the situation.
I am trying to do this as simple as possible, I studied Yarn Workspaces for a while, but that's a solution that's currently doesn't work with Electron, there were simply too many issues.
I have am Electron project here: ./electron/
I have a directory with components here: ./common/
The components are developed in React/JSX, there is nothing really fancy about them. That said, I am using hooks (useXXX).
I tried many ways to include those components (ideally, I wanted to use Yarn Workspaces, but it only multiplied the number of issues), but they all failed. Which is why I would like to avoid using yarn link or workspaces or making the common a library, etc. I just want my Electron project to behave as if the files were under ./electron. That's it.
The closest I came to a solution is by using electron-webpack, and overriding it with this config:
module.exports = function(config) {
config = merge.smart(config, {
module: {
rules: [
{
test: /\.jsx?$/,
//include: /node_modules/,
include: Path.resolve(__dirname, '../common'),
loaders: ['react-hot-loader/webpack', 'babel-loader?presets[]=#babel/preset-react']
},
]
},
resolve: {
alias: {
'#common': Path.resolve(__dirname, '../common')
}
}
})
return config
}
I can import modules, and they work... except if I use hooks. And I am getting the "Invalid Hook Call Warning": https://reactjs.org/warnings/invalid-hook-call-warning.html.
I feel like that /common folder is not being compiled properly by babel, but the reality is that I have no idea where to look or what to try. I guess there is a solution for this, through that webpack config.
Thanks in advance for your help :)
I found the solution. That happens because the instance of React is different between /common and /electron.
The idea is to add an alias, like this:
'react': Path.resolve('./node_modules/react')
Of course, the same can be done for other modules which need to be exactly on the same instance. Don't hesitate to comment this if this answer it not perfectly right.
I wrestled more than a day with a similar problem. My project has a dependency on a module A that is itself bundled by Webpack (one that I authored myself). I externalised React from A (declaring it to be a commonjs2 module). This will exclude the React files from the library bundle.
My main program, running in the Electron Renderer process, uses React as well. I had Webpack include React into the bundle (no special configuration).
However, this produced the 'hooks' problem because of two instances of React in the runtime environment.
This is caused by these facts:
module A 'requires' React and this is resolved by the module system of Electron. So Electron takes React from node_modules;
the main program relies on the Webpack runtime to 'load' React from the bundle itself.
both Electron and the Webpack runtime have their own module cache...
My solution was to externalise React from the main program as well. This way, both the main program and module A get their React from Electron - a single instance in memory.
I tried any number of aliases, but that does not solve the problem as an alias only gives direction to the question of where to find the module code. It does nothing with respect to the problem of multiple module caches!
If you run into this problem with a module that you cannot control, find out if and how React is externalised. If it is not externalised, I think you cannot solve this problem in the context of Electron. If it is externalised as a global, put React into your .html file and make your main program depend on that as well.
I'm writing a Chrome Extension using ES6/React/Redux babel and Gulp.
I was using babel presets es2015, stage-2 and react.
Then I realized as I'm only targeting Chrome I could get rid of the es2015/estage-2 stage as it's supported by Chrome.
So the first I tried was to get the .babelrc and remove the references to es2015 and stage-2.
Not so fast... Before running webpack gulp script fails to run.
What I tried first was to make only the gulp file ES5 compatible.
Then I got errors of spread operators not being supported, so I re-added "stage-2" loader.
Then I got errors in different modules:
> WARNING in ./background/src/index.html Module parse failed:
> /my_path/my_project/src/index.html Unexpected token (1:0) You may need
> an appropriate loader to handle this file type. SyntaxError:
> Unexpected token (1:0)
> at Parser.pp$4.raise (/my_path/my_project/node_modules/acorn/dist/acorn.js:2221:15)
To help to understand how my code is structured, it's in 3 main folders:
background, content and popup. Each one representing a Chrome environment.
For each one, I have a separated webpack.config.js file, similar to this one: https://pastebin.com/hseVyQaw
Gulp then calls webpack for each config file and generated the bundle output file for each one, during the build process.
There's a way to make Gulp/Webpack works with ES6 syntax, while not transpiling it for the deployment?
What's the best approach for this issue?
Gulp version
> [17:32:27] Requiring external module babel-register
> [17:32:27]CLI version 3.9.1
> [17:32:27] Local version 3.9.1
Webpack version: 1.14.0
UPDATE
After adding html-loader as suggested by #Michael Jungo it seems to run fine, but it gives me a warning, not sure how bad is to ignore it:
WARNING in ./background/src/index.js
Critical dependencies:
17:29-52 the request of a dependency is an expression
# ./background/src/index.js 17:29-52
UPDATE 2
Oh, Chrome is complaining about modules syntax of my extension, but based on what I read it's suppose to be supported:
Uncaught SyntaxError: Unexpected token import
Your error is not related to babel or any ES6 features. You're trying to import the HTML file ./background/src/index.html but in the config you've posted, there is no rule for .html that could handle these files, therefore webpack tells you that you might need an appropriate loader for this file type.
You can use the html-loader and add the following rule to your loaders array:
{
test: /\.html$/,
loader: 'html-loader'
}
As for your babel config, it should work as you wanted. Keep in mind if you're using ES modules (import/export) you would still need to transpile them or switch to webpack 2 which supports them out of the box. Also UglifyJs doesn't understand ES6 syntax, if you want to uglify ES6 you have to use an alternative like babili with the babili-webpack-plugin.
I'm trying to figure out how to make my unit tests in my reactJS ES6 application. My application is already using es6 module system, transpiled with jspm/babel to systemJs.
I found babel-jest as preprocessor but even with it, I can't run my tests because jest can't find SystemJs. ("System is not defined" error is shown in the console)
In the browser, as explained in jspm documentation, SystemJs is loaded globally. I guess I should load SystemJs inside my preprocessor, but How can I make systemJs available for loading additional modules in my tests?
Thanks in advance
Unfortunately, Jest does not support SystemJS ES6 modules at the moment.
See the following comments:
So it sounds like jest assumes that your modules resolve based on the Node resolution algorithm.
Unfortunately this isn't compatible with SystemJS's resolution algorithm.
If there was a way in jest to set a "custom resolver" algorithm through an API then we could plug jspm into jest, but I'm not sure if this is currently possible.
-- Comment by Guy Bedford, creator of SystemJS, Jun 2015
It is unlikely there'll be official support for [SystemJS] unless it is a community contribution.
-- Comment by #cpojer, Jest Collaborator, Jan 2016
Also see the following issue: Invalid URL is thrown when requiring systemjs in jest test cases
in essence to get Jest to play nice with an app running on JSPM/SystemJS you need to "teach" it about all the mapping it holds in the config.js file (or however you call System.config())
the long answer is that you need to create an entry for each dependency you have installed with JSPM like this:
//jest configuration
moduleNameMapper: {
...
"^redux$": "redux#3.6.0",
...
}
for each alias you have, you need at least one entry:
moduleNameMapper: {
...
"^common\\/(.*)": "<rootDir>/src/common/$1", //for a dir alias
"^actions$": "<rootDir>/src/actions/index", //for a file alias
...
}
you also need to have these mappings in your nodeNameMapper:
moduleNameMapper: {
...
"^npm:(.*)": "<rootDir>/jspm_packages/npm/$1",
"^github:(.*)": "<rootDir>/jspm_packages/github/$1",
...
}
and finally, you need to have this moduleDirectories config:
moduleDirectories: ["node_modules", "jspm_packages/npm", "jspm_packages/github"]
this isnt really practical because you dont want to keep two copies of all your dependencies registry and have to sync them when they change...
so the short and better answer, you use my gulp-jest-jspm plugin :)
even if you dont use gulp, you can use its getJestConfig() method to generate the config for you before you run Jest.