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.
Related
In my MessageItem.tsx component I have the following code:
const data = useFragment(
graphql`
fragment MessageItem_message on Message {
date
body
}
`,
message as any
);
After running relay-compiler --src ./src --schema ../../schema.graphql --language typescript --artifactDirectory ./src/__generated__, a module named MessageItem_message.graphql.ts gets generated.
But when I run the app it gives me an error:
Failed to compile.
./src/components/MessageItem.tsx
Module not found: Can't resolve
'./__generated__/MessageItem_message.graphql'
The reason is only components at the src root can refer to the right path (./__generated__), whereas components in a folder actually need to refer to the path (../__generated__) but it's not doing so.
How can I configure the path?
Edit .babelrc to point to the artifactDirectory
// .babelrc
{
"plugins": [
[
"relay",
{
"artifactDirectory": "./src/ui/graphql/types"
}
]
]
}
Remove "--artifactDirectory ./src/__generated__" from the relay-compiler options.
By default it seems the Relay compiler puts a "__generated__" directory in the directory with any source code containing GraphQL.
As a result any "./__generated__" references anywhere and at any level in the source code hierarchy now work as they should.
Thanks to #ThibaultBoursier for the pointer.
PS I wonder if the --artifcactDirectory option is just meant to be used to change the name of the artifact directory, rather than its location?
Just moments ago I ran into the same issue. The reason is that the relay-compiler is using the artifactDirectory setting to decide where to put the generated files, but the babel-plugin-relay exposing the graphql tag needs to get the very same argument otherwise it just attempts to include a colocated relative file.
I fixed it in my case by configuring the plugin with a babel-plugin-macros.config.js file as follows (where the artifactDirectory is the same as the one supplied to the relay-compiler):
module.exports = {
relay: {
artifactDirectory: "./src/ui/graphql/types",
},
};
This solution assumes you are using the macro via babel-plugin-macros, otherwise you might need to supply that argument via the .babelrc file but I have no experience with that unfortunately.
i keep getting the error:
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.
plugins: [
['some-plugin', {}],
['some-plugin', {}, 'some unique name'],
]
this is my babelrc with the changes it is asking for:
{
"presets": [
["#babel/env"],
["#babel/preset-react"]
],
"plugins": [
["#babel/plugin-syntax-jsx"],
["#babel/plugin-transform-react-jsx"],
["#babel/plugin-transform-react-display-name"],
["#babel/plugin-transform-react-jsx-self"],
["#babel/plugin-transform-react-display-name"]
]
}
Not really sure where i have the wrong syntax for the file. Also this is my first time configuring webpack4 with babel for a react application. Please let me know if everything looks fine for this to work with react.
Like the error says: you have a duplicate. ["#babel/plugin-transform-react-display-name"] is in your "plugins" array twice. Just delete one of them.
With that said: take a look at what's already included in preset-react (a preset is a pre-defined bundle of plugins). All of those plugins are already included (though "plugin-transform-react-jsx-self" is behind an option.)
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.
I have questions about babel.rc config file.
I searhed and saw two different config file examples.
{
"presets": [["es2015", { "modules": false }]],
"plugins": ["syntax-dynamic-import"]
}
and
{
"presets": [
[
"env",
{
// leave imports as they are
"modules": false
}
]
],
"plugins": [
// support dynamic import syntax, but leave it unchanged
"babel-plugin-syntax-dynamic-import"
]
}
My questions are:
1)What is the difference between es2015 preset and env preset?
2)Why do we need modules option to be false?I understood that it
instructs Babel to not try and parse the imports.But why exactly do we need that?
3)And how about dynamic imports?Why do we need to use plugin?Is there any relation between modules:false option?
4)What about browser support for the dynamic imports?Can babel transform it to ES5?Can dynamic imports and code splitting work with IE10 or IE11?How can we figure that which browser supports dynamic imports and code splitting?
Ad 1 - babe-preset-es2015
This is deprecated. If you want to stay up to date, use the env preset
Note from authors:
instead of making more yearly presets 😠, Babel now has a better
preset that we recommend you use instead: npm install babel-preset-env
--save-dev. preset-env without options will compile ES2015+ down to ES5 just like using all the presets together and thus is more future
proof
Ad 2 - Modules is set to false to ensure that import statements are left as is (opposed to transpiling them to require). For example: You can do this to give Webpack the ability to statically analyze our code to produce more efficient bundles.
Ad 3 - It allows parsing of import(). I do not know if there is a relation to modules option.
Ad 4 - 'Note: Dynamic import() is available in Chrome 63 and Safari Technology Preview 24' -> source: Dynamic imports
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.