Codemirror - Module parse failed: Unexpected token - reactjs

I am using react-codemirror2. I used npx create-react-app appname to create my app.
But when I try to run the development server it gives me the following error -
./node_modules/codemirror/mode/rpm/changes/index.html 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
> <!doctype html>
|
| <title>CodeMirror: RPM changes mode</title>
One solution suggested to change the modulesDirectories. I tried doing so using npm run eject. But wasn't successful at doing it.
Please help me with the same

Go to solutions section if you are in a hurry.
The why
The reason for this error is the way bundling dynamic imports works in webpack. Imports go by providing a starting part of a path and you may refine that through an end part that holds a path that precise an extension.
Ex:
import(`codemirror/mode/${snippetMode}/${snippetMode}`)
ref: https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import
Such an import is processed by webpack through the following regex ^\.\/.*$. That we can see in the error message:
| <title>CodeMirror: RPM changes mode</title>
# ./node_modules/codemirror/mode/ sync ^\.\/.*$ ./rpm/changes/index.html
And that's basically to determine the possible modules. And bundle them as chunks for code splitting.
Because of that open matching regex. So all files of all types (extensions) are matched. Then depending on the extension. The correct loader would be used. If we had the html-loader setup and configured through a rule. That wouldn't fail. As the loader will handle that module (webpack module [html]). Even though that can be an option to handle the problem. It wouldn't be the right thing to do. As it would create an extra bundle for the module. And also some entries for it. In the main bundle.
Dynamic Imports types and there resolution
All types get code splitted (chunks created for them for code splitting). Except for the last one.
Absolute full path. (static) ==> Imported dynamically and code splitted.Ex:
import('codemirror/mode/xml/xml')
The exact path and module will be resolved and a chunk for it will be created.
Dynamic path with a starting path.
Ex:
import(`codemirror/mode/${snippetMode}/${snippetMode}`)
All paths with this regex codemirror\/mode\/.*$ are matched.
Dynamic path with a starting path and an ending path with extension as well.ex:
import(`./locale/${language}.json`)
All paths with the following regex would be matched ./locale/.*\.json which limit it to .json extension module only.
Full variable import.Ex:
import(someVar)
Doesn't create code splitting at all. Neither tries to match. Because it can match just quite anything in the project. Even if the variable is set to a path someVar = 'some/static/path'. It wouldn't check and resolve the variable association.
The solutions
No electron or electron.
module.noParse
module: {
noParse: /codemirror\/.*\.html$/,
rules: [
// ...
noParse tell webpack to not parse the matched files. So it both allows us to exclude files and boost the performance. It works all great. And can be one of the best solutions as well. You can use a regex. Or a function.
ref: https://webpack.js.org/configuration/module/#module-noparse
Don't use the import('some/path' + dynamicEl) format and use instead
const dynamicPath = 'some/path' + dynamicEl
import(dynamicPath) // That would work just ok
Use magic comments [wepackExclude or wepackInclude] with import (if electron and using require => convert require to import + magic comment). Magic comments don't work with require but only import.
ex:
import(
/* webpackExclude: /\.html$/ */
`codemirror/mode/${snippetMode}/${snippetMode}`
)
or even better
import(
/* webpackInclude: /(\.js|\.jsx)$/ */
`codemirror/mode/${snippetMode}/${snippetMode}`
)
Include allows us to make sure we are targeting exactly what we want to target. Excluding HTML. May still create chunks for some other files that are not .js. It's all relative to what we want. If you want to include only a specific extension. An include is better. Otherwise, if we don't know. And some other extension would be required. Then an exclude is better.
ref: https://webpack.js.org/api/module-methods/#magic-comments
Magic comments examples and usage:
// Single target
import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackExports: ["default", "named"] */
'module'
);
// Multiple possible targets
import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`./locale/${language}`
);
And to fully ignore code splitting
import(/* webpackIgnore: true */ 'ignored-module.js');
If nodejs or electron and the import should be processed as commonjs require. Use the externals config property like in the example bellow:
externals: {
'codemirror': 'commonjs codemirror'
}
which works like this. Webpack for any import with codemirror (left part). convert it to the commonjs import without bundling it (right part).
import(`codemirror/mode/${snippetMode}/${snippetMode}`)
will be converted to:
require(`codemirror/mode/${snippetMode}/${snippetMode}`)
instead of bundled.
extenals doc ref: https://webpack.js.org/configuration/externals/#externals
If electron. And the feature should not be bundled. use window.require for all nodejs electron API calls (Otherwise set it on entry file window.require = require). And use it instead.
Its electron, nodejs ==> Webpack stay the hell out of this

The doctype declaration is incorrect, it should have been:
<!DOCTYPE html>
Notice DOCTYPE should be in caps.

Related

React Js : Module parse failed: Unexpected token

I keep getting below error in my react app. Not sure what is the issue.
/Users/823222/miniapp/node_modules/headers-polyfill/lib/Headers.js 9:25
Module parse failed: Unexpected token (9:25)
File was processed with these loaders:
../../node_modules/source-map-loader/index.js
You may need an additional loader to handle the result of these loaders.
| class HeadersPolyfill {
| // Normalized header {"name":"a, b"} storage.
[NORMALIZED_HEADERS] = {};
| // Keeps the mapping between the raw header name
| // and the normalized header name to ease the lookup.
Looks like this is due to a recent change in this package, that changed how the symbols were declared:
https://github.com/mswjs/headers-polyfill/pull/33/files
I've started a GitHub issue here, feel free to add details about your environment:
https://github.com/mswjs/headers-polyfill/issues/36
TL;DR: There was a significant change to how the module is prepared in a recent release, I reverted to 3.0.4 and things are working again for me.
Edit:
3.0.10 released that reverts the build target and fixes this issue:
https://github.com/mswjs/headers-polyfill/releases/tag/v3.0.10

Export module via Webpack

I am working on a React app. In index.js am exporting some variables, e.g.
export const a="Hello";
export const b=[1,2,3];
In webpack.config.js:
...
output: {
...
library: "myApp",
libraryTarget: "window"
},
...
I know window.myApp is now a module which includes all the exported variables from index.js. What I do not know is how the above works. How this module is being created and why it includes only the exports from index.js and not other files as well? How, may I include exports from another specific file?
Your module is being created based on the entry configuration and the other modules and plugins that you configure and is converted to a build file based on the configuration provided in the output config of webpack.
library setup is tied to the entry configuration so if you specify the entry to be index.js, your exports from within the index.js are available within the build
In order to also expose exports from other files, you can import and export them from the index file like
export { default as SomeFunction} from 'some-function.js';
According to the webpack docs:
For
most libraries, specifying a single entry point is sufficient. While
multi-part libraries are possible, it is simpler to expose partial
exports through an index script that serves as a single entry point.
Using an array as an entry point for a library is not recommended.
libraryTarget specifies how the module is exposed. For instance in your case your module is exposed on the window object.
You can expose the library in the following ways:
Variable: as a global variable made available by a script tag (libraryTarget:'var').
This: available through the this object (libraryTarget:'this').
Window: available through the window object, in the browser (libraryTarget:'window').
UMD: available after AMD or CommonJS require (libraryTarget:'umd').
If library is set and libraryTarget is not, libraryTarget defaults to
var as specified in the output configuration documentation. See
output.libraryTarget there for a detailed list of all available
options.
You have two solution to include other files
First is to use multiple entries in your webpack module
module.exports = {
// mode: "development || "production",
entry: {
A: "./CompA",
B: "./CompB"
},
Second approach is use one entry like your solution, but need to add wrappere.js
wrapper.js
import * as a from './CompA.js'
import * as b from './CompB.js'
export a,b
And your wrapper become the single entry, where you can access later wrapper.a,wrapper.b
module.exports = {
// mode: "development || "production",
entry: {
app: "./wrapper.js",
},

TypeScript with Relay: Can't resolve generated module

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.

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.

`_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