I followed https://zellwk.com/blog/publish-to-npm/ to create my custom npm package (https://www.npmjs.com/package/demo-to-publish). The folder structure of my custom package is as follows:
Content of my package.json is as follows:
{
"name": "demo-to-publish",
"version": "1.0.5",
"description": "testing publishing to npm",
"main": "./src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open --mode development",
"build": "webpack --mode production"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/preset-env": "^7.8.4",
"@babel/preset-es2015": "^7.0.0-beta.53",
"@babel/preset-react": "^7.8.3",
"babel-loader": "^8.0.6",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
"babel-preset-es2015": "^6.24.1",
"react": "^16.12.0"
}
}
Contents of my index.js in src folder are as follows:
import React, { Component } from "react";
export default class Button extends Component {
render() {
return (
<div>
<button>Click me</button>
</div>
);
}
}
Contents of my webpack.config.js are as follows:
module.exports = {
entry: "./src/index.js",
output: {
filename: "index.js"
},
module: {
rules: [
{
test: /\.js$|jsx/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env","@babel/preset-react"]
}
}
}
]
}
};
After publishing it to npm I installed it using npm i demo-to-publish
in my new react cra app. I wrote the following code to use this package.
import Button from "demo-to-publish";
<Button/>
The error I am facing is in the screenshot attached below.
How to resolve this issue? Help me out as this is my first time publishing an npm package.
The issue is that your code is not transpiled
and so it is not properly recognised by the browser and hence errors. By default, create-react-app does not transpiles node_modules.
You can find more here in a github issue https://github.com/facebook/create-react-app/issues/3889
The node module has no errors, just transpilation is the problem.
After going through the repo (https://github.com/prak-mtl/demo-to-publish), there are 2 possible fixes which can be done and are listed below. Recommended solution will be 2nd one but it requires you to do the build and then publish
For this you need to do some changes in the both CRA and npm repo. You need to add a configuration in the babel config to transpile the specific node module. Since, CRA config is not changeable (unless you ejected the code), you need to add a additional configuration using override
option.
Inside the package.json of the npm package (i.e. https://github.com/prak-mtl/demo-to-publish/blob/master/package.json), you need to change the main path since we will be transpiling the code to new folder lib
. Change it to ./lib/src/index.js
and republish the package.
<any-name>.js
, here let's say babel_override.js
)module.exports = {
overrides: [
{
test: ["./node_modules/demo-to-publish"],
presets: ["@babel/preset-react"]
}
]
}
This will be used to transpile the code inside demo-to-publish
in the node_modules folder in the CRA app
You should have @babel/preset-react
installed. If not, then install it.
Delete and reinstall the demo-to-publish package in CRA app.
Before running the project, code needs to be transpiled, so run the following command in the terminal
NODE_ENV=development ./node_modules/.bin/babel ./node_modules/demo-to-publish -d ./node_modules/demo-to-publish/lib --config-file ./babel_override.js
-d ./node_modules/demo-to-publish/lib
will published the transpiled code inside lib folder --config-file
is the babel override config created in step 1. You should get success result of type: Successfully compiled 3 files with Babel.
This approach requires you to build the npm package. Since you already have the webpack, it shouldn't be a problem. The following steps needs to be done in demo-to-publish
repo
commonjs2
in the output. The webpack config will become something like this:module.exports = {
entry: "./src/index.js",
output: {
filename: "index.js",
libraryTarget: 'commonjs2' //This one the most important line, others things will remain same
},
module: {
//Other code
}
};
This will be used to output the build in dist
folder.
./src/index.js
to ./dist/index.js
dist
containing one index.js
file inside itThen, in the CRA app, install the package and run normally. It should work fine.
Hope it helps. Revert for any doubts.