1

I'm trying to create my libary with React and to use it locally (with my company git repository).

I can test my app while developping with npm run start. My app is running.

But when I want to use it in an other project, I got this error :

ERROR in ./node_modules/mylib/src/views/calendar.jsx Module parse failed: Unexpected token (10:53) You may need an appropriate loader to handle this file type.

The line involved is :

const Calendar = ({ month = moment(), dayCellTitle = <DayCellTitle />, header = <CalendarHeader/>, children }) => {

The package is imported like that :

"mylib": "git+ssh://[email protected]:mylib/mylib.git"

I try this, but I got worst :

Plugin/Preset files are not allowed to export objects, only functions. In /home/xxxxx/Documents/workspaces/react-calendar/node_modules/babel-preset-stage-0/lib/index.js

Here the files of my package :

webpack.config.js

const path = require('path');
const pkg = require('./package.json');
const libraryName= pkg.name;
module.exports = {
  output: {
    path: path.join(__dirname, './dist'),
    filename: 'react-calendar.js',
    library: libraryName,
    libraryTarget: 'umd',
    publicPath: '/dist/',
    umdNamedDefine: true
  },
  module: {
    rules: [
      { test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      }
    ]
  },
  resolve: {
    alias: {
      'react': path.resolve(__dirname, './node_modules/react'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
    }
  },
  externals: {
    // Don't bundle react or react-dom
    react: {
      commonjs: "react",
      commonjs2: "react",
      amd: "React",
      root: "React"
    },
    "react-dom": {
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "ReactDOM",
      root: "ReactDOM"
    }
  }
};

package.json

{
  "name": "react-calendar",
  "version": "0.0.1",
  "description": "React Calendar UI by",
  "main": "./dist/lib/index.js",
  "scripts": {
    "start": "./node_modules/.bin/parcel docs/index.html",
    "build": "./node_modules/.bin/webpack --mode=production",
    "build:docs": "./node_modules/.bin/parcel build docs/index.js -d ./dist/docs && cp docs/index.html dist/docs/index.html",
    "test": "jest",
    "tdd": "jest --watch"
  },
  "author": "Xero",
  "license": "MIT",
  "dependencies": {
    "lodash": "^4.17.11",
    "mobx": "^5.9.0",
    "mobx-react": "^5.4.3",
    "moment": "^2.24.0",
    "moment-range": "^4.0.1",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.85.0",
    "settings": "^0.1.1"
  },
  "peerDependencies": {
    "lodash": "^4.17.11",
    "mobx": "^5.9.0",
    "mobx-react": "^5.4.3",
    "moment": "^2.24.0",
    "moment-range": "^4.0.1",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.85.0",
    "settings": "^0.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-0",
    "@babel/plugin-proposal-class-properties": "^7.3.0",
    "@babel/plugin-proposal-decorators": "^7.3.0",
    "@babel/preset-env": "^7.3.1",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "babel-plugin-module-resolver": "^3.1.3",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "enzyme": "^3.8.0",
    "enzyme-adapter-react-16": "^1.9.1",
    "jest": "^24.1.0",
    "parcel-bundler": "^1.6.2",
    "react-test-renderer": "^16.8.0",
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.12",
    "webpack-node-externals": "^1.6.0"
  },
  "jest": {
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/spec/javascript/__mocks__/fileMock.js",
      "\\.(css|scss|less)$": "<rootDir>/spec/javascript/__mocks__/styleMock.js"
    },
    "roots": [
      "src",
      "tests"
    ],
    "moduleFileExtensions": [
      "js",
      "jsx"
    ],
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "setupFiles": [
      "<rootDir>/tests/setup.js"
    ]
  }
}

.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react",],
  "plugins":  [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ]
}

Side question :

Is there a way to know if the library will be imported without error BEFORE doing the importation in an other project

Edit

I have added yarn run build to my package.json, and launching it do not raise any errors :

Entrypoint main [big] = react-calendar.js
 [45] (webpack)/buildin/module.js 497 bytes {0} [built]
 [48] (webpack)/buildin/global.js 472 bytes {0} [built]
[244] ./node_modules/moment/locale sync ^\.\/.*$ 3 KiB {0} [optional] [built]
[368] ./src/index.js + 52 modules 182 KiB {0} [built]
      | ./src/index.js 65 bytes [built]
      | ./src/views/calendar.jsx 1.17 KiB [built]
      | ./src/views/day_cell_title.jsx 358 bytes [built]
      | ./src/views/calendar_header.jsx 1.15 KiB [built]
      | ./src/store/calendar_store.js 3.85 KiB [built]
      | ./src/views/calendar_grid.jsx 1.49 KiB [built]
      | ./src/views/calendar_navigation_button.jsx 928 bytes [built]
      | ./src/views/calendar_title.jsx 290 bytes [built]
      | ./src/generators/month_generator.js 556 bytes [built]
      | ./src/painters/day_cell_color.js 593 bytes [built]
      | ./src/views/day_cell_content.jsx 547 bytes [built]
      | ./src/settings.js 332 bytes [built]
      | ./src/painters/event_color.js 374 bytes [built]
      | ./src/painters/range_color.js 591 bytes [built]
      | ./src/views/empty_day_cell_content.jsx 340 bytes [built]
      |     + 38 hidden modules
    + 743 hidden modules
2
  • Does the ./node_modules/mylib/src/views/calendar.jsx actually exist? Commented Feb 8, 2019 at 15:48
  • @jayarjo yes it does Commented Feb 8, 2019 at 15:56

3 Answers 3

4

You're redistributing your sources that contain JSX syntax. Usually, before publishing, you'll need to transform these. If not, then your dependents will need to configure their babel-loader with React support and ensure that they're not excluding your package modules.

So your configuration looks alright, except for the exclusion match:

 module: {
  rules: [
    { test: /\.(js|jsx)$/,
      exclude: /node_modules/,
      use: ['babel-loader']
    }
  ]
 }

I would recommend that you use { include } and list out the paths that should explicitly match. To find the path at which your package sources are located, use path.dirname(require.resolve('@yours/package-name')).

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

5 Comments

before publishing, you'll need to transform these how ?
@Xero for a good example I would recommend looking at some of your favorite published packages from the React ecosystem. If you start in package.json and observe the { scripts: { publish, prepublish } }, in most cases you should see invocations to some build tool that will have Babel configured to transform JSX syntax to createElement() calls for distribution. I would also like to point out that you do not need to do this or make this exclusive--it is just something done as common practice to help dependents use your package to avoid syntax errors and not have to introduce build tooling.
I would offer you a more complete example from react-virtualized. The published package for distribution contains several different kinds of builds, each suitable for a different audience with specific tooling. See github.com/bvaughn/react-virtualized/blob/… and you can inspect the different builds distributed here unpkg.com/[email protected]/dist.
Thank for your help, I figured out the issue, see my answer (a noob issue BTW)
@Xero congrats and happy package publishing 🙌!!! I think getting things right for the first package is always the hardest, but before you know it there will be dozens of your packages in the registry and we will all benefit from your hard work 🙇!
2

The issue was 2 things :

1. Build forgotten and not commited

I was not building my project (with yarn run build), and most of all, I was not commiting the compiled file (dist/main.js)

2. The import was wrong

Given the point 1., my import were wrong.

I was doing :

import {Calendar} from "project-react-calendar/src/views/calendar";

instead of :

import {Calendar} from "project-react-calendar";

That can be available, with this index.js :

import { Calendar } from './views/calendar'

export {
    Calendar
}

Comments

1

Your npm run start script seems to use parcel, not webpack I guess webpack.config.js simply doesn't affect it? Maybe you should make sure that proper loader is indeed launched by parcel.

"start": "./node_modules/.bin/parcel docs/index.html", // <- invokes parcel bundler
"build": "./node_modules/.bin/webpack --mode=production",

Try npm run build and if it succeeds, that will be exactly the case.

8 Comments

thx for your answer. see my edit. launching webpack do not raise error
Then you got to fix your parcel config.
The Module parse failed issue is still there
Yes it did, but when I try to add my lib to an other project, I got the Module parse issue, this is so weird
Are you saying that the project that will include my lib, will call the lib yarn run start and that's because it failed ?
|

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.