Reputation: 4331
So I am trying out monorepo design with lerna
for our react applications.
the idea is to create one repo which will have all the react projects as lerna
packages as well as some common modules/components which are shared across the applications.
now all these common modules/components are es6 modules. which are not transpiled. because there is continuous development going on the common modules as well. and if we build/transpile them I am sure react HMR will not work after that (a wild guess). following is my directory structure
package.json
lerna.json
|--packages
|--common
|--react-app
|--constants
|--utilities
common
contains common react elements like table,accordion
etc. which are exported as default es6 modules.
react-app
imports common
as dependency
. react-app
has webpack build configuration set.
now when i import common
module into my react-app
babel transform
fails with this error
Button.component.jsx 7:19
Module parse failed: Unexpected token (7:19)
You may need an appropriate loader to handle this file type.
| const { Search } = Input;
| class TextBoxWithButton extends React.Component {
> static propTypes = {
| placeholder: PropTypes.string.isRequired,
| onAction: PropTypes.func.isRequired,
@ ./src/App/Modules/Todo/Components/Header/Header.component.jsx 10:0-111 16:25-41
@ ./src/App/Modules/Todo/Todo.component.jsx
@ ./src/App/Router/index.jsx
@ ./src/App/Layout/index.jsx
@ ./src/App/index.jsx
@ ./src/App.hot.js
@ ./src/index.jsx
which means babel-loader
is unable to parse and transpile whats in the node_nodules
folder which makes sense because all dependencies are expected to be already transpiled. but not always. if you manage local dependencies you cannot keep them build all the time (that's what i think)
now I have found some solutions online that enable 1bable-loader
not to exclude node_modules
or ignoring @mypackage
in exclude regex. but nothing is working in my case.
here is what i have tried so far.
exlucde: /node_modules/
from babel-loader
=> not workingrequire.resolve('babel-loader')
=> not workingresolve.symlinks= false
.resolve.modules='node_modules'
or
path.resove(__dirname,'node_modules')
=> not workingbabel-loader
include include: [srcPath, lernaPackagesPath]
,nothing seem to work. is there something that i am missing ? here is the link to my git test repo.
Upvotes: 3
Views: 3663
Reputation: 4331
babel-loader
by default will not transpile anything that is in node_modules
. you can explicitly say what to transpile in node_modules
but after @babel7.0.0
that doesn't seem to work either.
there is also a scope of .babelrc
which was introduced in @babel7.0.0
.
according to the research i did in under normal circumstances node_modules
expect to have transpiled commonjs
or umd
modules. which can be imported by any application. in my case my packages/components where all es6
modules which needed to be transpiled. and my webpack build was failing because babel-loader
was simply ignoring them.
so i decided to use @babel/cli
to transpile each package where my components reside i had to add .babelrc
along with other configurations to my component packages and build them with @babel/cli
here is the scripts
in my package.json
"scripts": {
"start": "babel src --watch --out-dir dist --source-maps inline --copy-files --ignore spec.js,spec.jsx"
},
and my package.json looks something like this after that
{
"name": "@pkg/components",
"version": "1.0.1",
"description": "a repository for react common components. may or may not be dependent on elements",
"main": "dist/index.js",
"author": "hannad rehman",
"license": "MIT",
"scripts": {
"start": "babel src --watch --out-dir dist --source-maps inline --copy-files --ignore spec.js,spec.jsx"
},
"dependencies": {
"@pkg/constants": "^1.0.1",
"@pkg/elements": "^1.0.1"
},
"peerDependencies": {
"prop-types": "^15.6.2",
"react": "^16.4.2",
"react-router-dom": "^4.3.1"
}
}
with this approach. all of my common packages will be unit tested, linted and built before any application can import them. babel
has a watch mode which will make sure transpilation happens always when a change occurs.
lastly and most importantly react HMR
works as expected.
UPDATE
the above solution definitely works but after months i changed it by using include property in the babel loader
{
test: /\.js(x?)$/,
include: [/node_modules\/@pkg/],
use: [
'thread-loader',
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
configFile: path.resolve(
__dirname,
'../../../../',
`${env.appConfig.folderSrc}/babel.config.js`,
),
},
},
],
}
Upvotes: 4