How to configure the webpack configurations in create-react-app - reactjs

I have a question or problem.
I'm using React v.16 so when I create a project I did with create-react-app that webpack is already preconfigured. And I want work with ol-cesium, and in npmjs I see that I have to:
create an alias to the goog directory. With webpack:
resolve: {
alias: {
'goog': path_to_goog,
}
}
If I dont create a webpack file show me this error:
./node_modules/olcs/AbstractSynchronizer.js
107:22-35 "export 'getUid' (imported as 'olBase') was not found in 'ol/index.js'
How can solve it??? And what is path_to_goog???
EDIT
Thanks to Shishir Anshuman for your help.
Now I add alias on webpack.config.dev.js and webpack.config.prod.js but some me a lot errors.
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Ol-Cesium
'goog': '../node_modules/olcs/goog',
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
In console show me this error:
./node_modules/olcs/AbstractSynchronizer.js
107:22-35 "export 'getUid' (imported as 'olBase') was not found in 'ol/index.js'
__stack_frame_overlay_proxy_console__ # index.js:2178
handleErrors # webpackHotDevClient.js:178
./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage # webpackHotDevClient.js:211
./node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent # eventtarget.js:51
(anonymous) # main.js:274
./node_modules/sockjs-client/lib/main.js.SockJS._transportMessage # main.js:272
./node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit # emitter.js:50
WebSocketTransport.ws.onmessage

In the Codesandbox provided by you, I was unable to find the root cause, but I noticed the following:
I noticed that you have used the ES6 import statement:import OLCesium from "olcs/OLCesium";.
But as per this issue, the module is not yet ported to ES6.
I have never used this library before, So it's hard to figure out what exactly is going on.
Did you try installing https://www.npmjs.com/package/geom ? Since the error says 4.6.4/geom/Point.js is missing.

Related

Typescript + webpack module resolution

I am having an issue with webpack/typescript correctly resolving modules.
Consider the below structure
Project files
src/models/item.ts
Dependencies
node_modules/#common/src/models/item.ts
node_modules/#common/src/models/container.ts
The #common module contains common libraries, that each project can use and extend base on its needs.
What I am trying to accomplish is that when the container.ts imports item.ts as
import item from "models/item";
Webpack should resolve the path to the project's path.
However, I am getting the one from the #common path
Below is the relevant part from CRA's ejected webpack config and the relevant tsconfig
webpack config
resolve: {
// This allows you to set a fallback for where webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules, "./src", "node_modules/#common/src"].concat(
modules.additionalModulePaths || []
),
tsconfig.json
"paths": {
"*": ["*", "src/*", "../node_modules/#common/src/*"]
},
I would expect this to be possible.
Am I missing something?
Thanks for any help

A fool-proof tsup config for a React component library

I've never published an NPM package before. All these details to generate a package seem way too complicated to my level. The only tool, that was beginner friendly, that I could find is create-react-library which recommended to switch to tsup instead.
I'm asking here to know if there's a batteries-included, most-cases-met, setup for tsup or any other tool of your recommendation for this kind of project (and I think this is a common scenario):
A React Project
Typed with Typescript
Tested with Jest
No dependencies
Exports React components
Should be public on NPM
If you want most-cases-met, batteries-included way to make a library like that then take a look at dts-cli. It will work but it will definitely be slower than tsup. I myself am in the process of switching a library with about 60 react components from dts-cli to tsup because the build time started taking too long (about a minute) on a MacBook Air M1.
Here is an example setup.
First you need to bundle each component separately. You can use a glob as an entry point in Tsup.
Keep in mind that options that works for Esbuild works for Tsup most of the time.
// tsup.config.ts
defineConfig([
{
clean: true,
sourcemap: true,
tsconfig: path.resolve(__dirname, "./tsconfig.build.json"),
entry: ["./components/core/!(index).ts?(x)"],
format: ["esm"],
outDir: "dist/",
esbuildOptions(options, context) {
// the directory structure will be the same as the source
options.outbase = "./";
},
},
Then you'll want to have a index.ts, for convenience, that expose named exports. This index is sometimes referred as a "barrel" file.
// index.ts
// the actual file is "Button.tsx" but we still want a ".js" here
export { Button } from "./components/core/Button.js";
Notice the .js extension. ESM expects explicit extensions so it's needed in the final build.
Adding the .js doesn't seem to bother TypeScript, which stills correctly recognize the type of "Button" from Button.tsx. At this point I am not sure why it works, but it does.
Transpile this index, without bundling.
// tsup.config.ts
{
clean: true,
sourcemap: true,
tsconfig: path.resolve(__dirname, "./tsconfig.build.json"),
entry: ["index.ts", "./components/core/index.ts"],
bundle: false,
format: ["esm"],
outDir: "dist",
esbuildOptions(options, context) {
options.outbase = "./";
},
},
])
Finally define your package.json as usual:
"sideEffects": false,
"type": "module",
"exports": {
".": "./dist/index.js"
},
sideEffects is a non-standard property targeting application bundlers like Webpack and Rollup.
Setting it to false tells them that the package is safe for tree-shaking.
Now import { Button } from "my-package" should work as you expect, and tree-shaking and dynamic loading at app-level become possible because "Button" is bundled as its own ES module Button.js, and the package is marked as being side-effect free.
This is confirmed by my Webpack Bundle Analyzer in a Next app:
Before (a single bundled index.js):
After (separate files means I can select more precisely my imports):
Final config available here (might be improved in the future)

Flow required module not found

Using Webpack 2, Flow 0.46.0
I have a pretty large app I am developing, so am using Webpack resolve modules to create alias import names e.g. '../../../../constants/ServiceURI' to 'constants/ServiceURI'
Everything works fine until I add flow. There must be a way to use mapper or resolve_dirname to fix this, but I cannot figure out how. No matter what I do it breaks flow.
I really want to use flow, but this is a blocker for me.
Project structure:
./flowconfig
./webpack.config.js
./src
/js
/constants
/actions
/...
/css
Webpack config looks like:
resolve: {
modules: [
path.resolve('./src/js'),
path.resolve('./src/js/constants'),
'node_modules'
],
extensions: ['.js', '.jsx']
Flow config looks like:
[ignore]
.*/node_modules/*
[include]
<PROJECT_ROOT>/src/js/
[libs]
[options]
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
esproposal.export_star_as=enable
esproposal.decorators=ignore
# Tried this
module.name_mapper='^constants$' -> '<PROJECT_ROOT>/src/js/constants'
# Tried using this too
module.system.node.resolve_dirname=./src/js
module.system=haste
munge_underscores=true
[version]
0.46.0
Flow Error:
rc/js/actions/ActionActivity.js:6
6: import { ACTIVITY_API } from 'constants/ServiceURI'
^^^^^^^^^^^^^^^^^^^^^^
constants/ServiceURI. Required module not found
The regular expression you're using in the module.name_mapper does not match constants/ServiceURI. It only matches exactly constants. You additionally need to match anything that comes after constants to be able to resolve all modules inside the constants directory.
module.name_mapper='^constants/\(.*\)$' -> '<PROJECT_ROOT>/src/js/constants/\1'
Where \( and \) create a capturing group (the slashes are required), which you can refer to as \1. For more information see module.name_mapper.

Flow seems not to respect include option?

I've setup my React project with a folder for common components I want to import directly.
src/
---components/
---common/
---/TextInput
---/TabSelector
Full folder structure from root
Each of these folders in common have a index.jsx (and other resources such as style etc) with and export default <name> statement.
So my webpack config has the following configuration:
resolve: {
modulesDirectories: [
'node_modules',
myCommonComponentsPath
]
}
which allows direct imports: import TextInput from 'TextInput'
Trying to add this to .flowconfig (according to flow's documentiation) is not working though:
[include]
./node_modules/
<PROJECT_ROOT>/src/components/common
This works with webpacks resolver (components load and work) but flow gives the following error:
9: import TextInput from 'TextInput';
^^^^^^^^^^^ TextInput. Required module not found
Any help would be appreciated.
How do I resolve this?
You need to use the module.system.node.resolve_dirname setting, which is different from the include setting. Since you are telling Webpack a new place to find modules, you also need to tell Flow about that new place.
[options]
module.system.node.resolve_dirname=node_modules
module.system.node.resolve_dirname=src/components/common
The paths are relative to the location of your '.flowconfig' file.

`_Symbol.'for'`: Is that actually valid ES6? Webpack built it from React source

I'm trying to take React 0.14 for a spin before I upgrade it in my project. However, with a simple "hello world" prototype, Webpack is throwing an error:
ERROR in ./~/react/lib/ReactElement.js
Module parse failed: /home/dan/Demos/reactiflux/node_modules/babel-loader/index.js!/home/dan/Demos/reactiflux/node_modules/react/lib/ReactElement.js Line 25: Unexpected string
You may need an appropriate loader to handle this file type.
| // The Symbol used to tag the ReactElement type. If there is no native Symbol
| // nor polyfill, then a plain number is used for performance.
| var REACT_ELEMENT_TYPE = typeof _Symbol === 'function' && _Symbol.'for' && _Symbol.'for'('react.element') || 0xeac7;
|
| var RESERVED_PROPS = {
# ./~/react/lib/ReactMount.js 18:19-44
I do have babel-loader configured, and when I downgrade to React 0.13, everything works. What really stands out to me, is _Symbol.'for', in the middle of the error message.
In react/lib/ReactElement.js on line 21 (not 25), that line looks much more correct, with square brackets around the 'for' key:
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
I assume that the code shown in the error message is either in an intermediate state during compilation, or is the final compiled output. Does anyone know what could cause Webpack to produce something that looks so wrong? Has anyone successfully used Webpack, Babel and React ~0.14.1 together yet?
update
There is an issue for this: https://github.com/babel/babel/issues/2377
It's closed, but it looks like it came back for me. This was fixed in 5.8.25, but I have 5.8.29 and I still hit the bug.
It appears that the problem has something to do with me including babel runtime. My .babelrc was copied from an older project:
{
"optional": "runtime",
"stage": 0
}
In this little hello-world demo, there is nothing that requires bundling the runtime, so I just removed it, after noticing that https://github.com/DominicTobias/universal-react/, which also uses the same build tools, does not need it. That was the only change I needed to make to get this to build.
My webpack config is super simple:
var path = require("path");
module.exports = {
entry: "./index.js",
output: {
path: path.join(__dirname, "/dist"),
filename: "index.min.js"
},
module: {
loaders: [{
test: /\.js$/,
loader: "babel"
}]
}
};
I guess that's what I get for copying a config file from a more complex project into what was supposed to be a simplest possible demo.
I see that there is a babel-plugin-runtime as well as a babel-runtime on NPM, but when I tried out BPR for the sake of completeness, Babel complains: Module build failed: ReferenceError: The plugin "runtime" collides with another of the same name. Since I don't actually need the runtime, the linked GH repo is a 404, and since this really belongs in the issue trackers after all, this is as far as I am going to take this for now.
No, that is not valid code. That was an issue in Babel project, but it has been fixed in the 6.0 version which was released recently.
I was run into this issue too, and now I have checked this with latest version, and it is works fine. Here is my test steps:
# install Babel and plugins
npm install babel-cli babel-preset-es2015 babel-plugin-transform-runtime
# install React
npm install react
# run babel against problem react file
./node_modules/.bin/babel node_modules/react/lib/ReactElement.js --plugins transform-runtime --presets es2015
It is provides valid output, so the issue seems to be resolved.
And there is good news for you, babel-loader for webpack already supports 6 version of Babel. Check out its docs for details

Resources