4

I have created react app which name is "create-react-app-npm". And in the ./src/index.js file I have exported component to use it npm package in the another project. Firstly I have run this code in my main root.

npm run eject and then next part of my project

This is the src/index.js in the create-react-app-npm folder

import React from 'react';
import './index.css';
import App from './App';

class ExportApp extends React.Component{
    render(){
        return(<App sayHi="hello There I am creating my first npm package"/>);
    }
}
export default ExportApp;


this is the package.json file in the create-react-app-npm folder

{
  "name": "create-react-app-npm",
  "version": "0.1.0",
  "main": "src/index.js",
  "dependencies": {
    "@babel/core": "7.5.5",
    "@svgr/webpack": "4.3.2",
    "@typescript-eslint/eslint-plugin": "1.13.0",
    "@typescript-eslint/parser": "1.13.0",
    "babel-eslint": "10.0.2",
    "babel-jest": "^24.8.0",
    "babel-loader": "8.0.6",
    "babel-plugin-named-asset-import": "^0.3.3",
    "babel-preset-react-app": "^9.0.1",
    "camelcase": "^5.2.0",
    "case-sensitive-paths-webpack-plugin": "2.2.0",
    "css-loader": "2.1.1",
    "dotenv": "6.2.0",
    "dotenv-expand": "4.2.0",
    "eslint": "^6.1.0",
    "eslint-config-react-app": "^5.0.1",
    "eslint-loader": "2.2.1",
    "eslint-plugin-flowtype": "3.13.0",
    "eslint-plugin-import": "2.18.2",
    "eslint-plugin-jsx-a11y": "6.2.3",
    "eslint-plugin-react": "7.14.3",
    "eslint-plugin-react-hooks": "^1.6.1",
    "file-loader": "3.0.1",
    "fs-extra": "7.0.1",
    "html-webpack-plugin": "4.0.0-beta.5",
    "identity-obj-proxy": "3.0.0",
    "is-wsl": "^1.1.0",
    "jest": "24.8.0",
    "jest-environment-jsdom-fourteen": "0.1.0",
    "jest-resolve": "24.8.0",
    "jest-watch-typeahead": "0.3.1",
    "mini-css-extract-plugin": "0.5.0",
    "optimize-css-assets-webpack-plugin": "5.0.3",
    "pnp-webpack-plugin": "1.5.0",
    "postcss-flexbugs-fixes": "4.1.0",
    "postcss-loader": "3.0.0",
    "postcss-normalize": "7.0.1",
    "postcss-preset-env": "6.7.0",
    "postcss-safe-parser": "4.0.1",
    "react": "^16.9.0",
    "react-app-polyfill": "^1.0.2",
    "react-dev-utils": "^9.0.3",
    "react-dom": "^16.9.0",
    "resolve": "1.12.0",
    "resolve-url-loader": "3.1.0",
    "sass-loader": "7.2.0",
    "semver": "6.3.0",
    "style-loader": "1.0.0",
    "terser-webpack-plugin": "1.4.1",
    "ts-pnp": "1.1.2",
    "url-loader": "2.1.0",
    "webpack": "4.39.1",
    "webpack-dev-server": "3.2.1",
    "webpack-manifest-plugin": "2.0.4",
    "workbox-webpack-plugin": "4.3.1"
  },
  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "jest": {
    "roots": [
      "<rootDir>/src"
    ],
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,ts,tsx}",
      "!src/**/*.d.ts"
    ],
    "setupFiles": [
      "react-app-polyfill/jsdom"
    ],
    "setupFilesAfterEnv": [],
    "testMatch": [
      "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
      "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
    ],
    "testEnvironment": "jest-environment-jsdom-fourteen",
    "transform": {
      "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
      "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
      "^.+\\.module\\.(css|sass|scss)$"
    ],
    "modulePaths": [],
    "moduleNameMapper": {
      "^react-native$": "react-native-web",
      "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
    },
    "moduleFileExtensions": [
      "web.js",
      "js",
      "web.ts",
      "ts",
      "web.tsx",
      "tsx",
      "json",
      "web.jsx",
      "jsx",
      "node"
    ],
    "watchPlugins": [
      "jest-watch-typeahead/filename",
      "jest-watch-typeahead/testname"
    ]
  },
  "babel": {
    "presets": [
      "react-app"
    ]
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1"
  }
}

I have run npm link in the terminal while I am in the root folder of my project.

After I have created this main project, I have also created npm_test project folder by using create-react-app npm_test code.

I have run npm link create-react-app-npm code to link previous main project which is create-react-app-npm and my second npm-test project.

My App.js file as follows in my npm-test project folder.

import React from 'react';
import './App.css';
import ExportApp from 'create-react-app-npm'

function App2() {
  return (
    <div className="App">
     <ExportApp/>
    </div>
  );
}

export default App2;

when I run npm start I could not run the project. I have got the error messages. I do not have any ideas what does it mean. What should I do?

Error is like this

Failed to compile.

../create-react-app-npm/src/index.js
SyntaxError: /home/semih/Desktop/create-react-app-npm/src/index.js: Unexpected token (7:15)

   5 | class ExportApp extends React.Component{
   6 |     render(){
>  7 |         return(<App sayHi="hello There I am creating my first npm package"/>);
     |                ^
   8 |     }
   9 | }
  10 | export default ExportApp;

I have expected to run ExportMain component in the npm-test project. What should be the path which I should follow?

3
  • The error means, your JSX has not been transpiled into valid JavaScript syntax. CRA in your main project does not transpile JSX from node_modules (component lib). Build your library for node - e.g. config from here, adjust your main field in package.json to be the dist index.js and you should be good to go. Commented Aug 31, 2019 at 16:34
  • Thank you for your answer. However my webpack-config file is different from any examples on the internet. I do not know how to configure it according to website which you have given above. My webpack-config file code sample is as follows; const getStyleLoaders = (cssOptions, preProcessor) => { const loaders = [ isEnvDevelopment && require.resolve('style-loader'), isEnvProduction && { loader: MiniCssExtractPlugin.loader, options: shouldUseRelativeAssetPaths ? { publicPath: '../../' } : {}, }, Commented Aug 31, 2019 at 18:08
  • (github.com/SemihOzden/npm_example) this is the my create-react-app-npm repository link. I want to create npm package with it in local and then import another react project in my local computer. What should I do with it? Commented Sep 1, 2019 at 12:00

1 Answer 1

5

Create React App/CRA is not the optimal tool to build and bundle npm packages, its main purpose is to create Single Page Applications. For component libraries, CRA team recommends to use more flexible toolchains.

As you have ejected CRA, you can still try to adjust Webpack config. Here is an example config with the essential settings targeting npm packages:

// simply way to exclude all node_modules from bundle.
// You can configure entries manually, too.
const nodeExternals = require('webpack-node-externals');

module.exports = {
  ...
  output: {
    // provide entry point exports via CommonJS / as npm package
    libraryTarget: "commonjs"
  },
  ...
  // ignore built-in modules like path, fs, etc.
  target: "node",
  // don't bundle node_modules with your library
  // external packages should be required
  externals: [nodeExternals()]
};

Concerning CRA, add those settings to the base config <root>/config/webpack.config.js. Possible Further adjustments:

output: {
  // give your main npm package file a static name
  // It should be stored to build/node_bundle.js
  filename: "node_bundle.js"
},

package.json:

"main": "build/node_bundle.js"

Last, build your library and require it in your client application.

Links:

Sign up to request clarification or add additional context in comments.

2 Comments

Very useful answer. I've been using CRA to create it for a long time, it bothered me for a few days. Consider packaging with rollup later. Thank you!
Does it create a separate CSS file? How to get this CSS linked to this JS bundle and accept tree shaking on production build when the library user importing component from this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.