'Module parse failed? I need help setting up Babel

I'm writing my first JavaScript library and I'm testing it locally with a React project. I'm not seeing any Typescript errors when I'm writing my code but when I run yarn start for the React project that it linked to I'm getting the following error:

ERROR in ../test-lib/src/add.ts 3:29

Module parse failed: Unexpected token (3:29)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| __webpack_require__.$Refresh$.runtime = require('/home/aaron/projects/react-projects/test-app/node_modules/react-refresh/runtime.js');
| 
> export default function add(a: number, b: number) {
|   return a + b
| }

I edited this question to simplify the problem after I did some research - which is it looks like I need to compile the typescript code in my library and export it to a dist folder? Then the React app that depends on it can use it.

I'm seeing articles about Babel and ones about Rollup and I'm confused about which I need (or both?) and why. Lots of outdated and incomplete/lazy tutorial articles that don't seem to help.

Can you help me set up what I need to get this to work? Here is the current file structure of my test library, test-lib:

node_modules/
src/
  add.ts
  index.js
package.json
tsconfig.ts
yarn.lock

Here are the contents of the pertinent files:

src/add.ts:

export default function add(a: number, b: number) {
  return a + b
}

src/index.js:

import add from './add'
export default add

package.json:

{
  "name": "test-lib",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

tsconfig.json:

{
  "include": ["src/**/*"],
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

I'm aware I'll have to install @babel/... packages and the plugin for @babel/preset-typescript but I've left this out in the example because I wanted a freshly untouched typescript library for simplicity's sake. Help me start from scratch here.

I have additional questions as well:

  • Can I have all my files in *.ts format or does the entry point need to be a javascript file? (I'm assuming any *.config.* files probably need to be *.js as you need to start with javascript first so you can set up typescript for the rest of the project, right?

  • I've heard that I should compile my code for commonjs as well as esnext. Does my choice affect the needed libraries or steps to run their React app by the user that depends on my library?

  • The library I'm writing depends on React but it won't have any jsx/tsx files. It will have some custom React hooks though. Do I need to include the @babel/preset-react plugin as well?



Solution 1:[1]

Rollup or Webpack are module bundler and they handle files bundling only. To transpile Javascript latest code to browser compatible code, we need transpilers like babel. There are plugins available for Rollup and Webpack to handle this transpiling of code, Babel is such a plugin.

So Babel and Rollup are different tools, we can use Babel inside Rollup for transpiling of Javascript.

Let's take Webpack as bundler for your questions

What about typescript ?

We need some plugin to convert it into js, there are plugins like ts-loader for Webpack

What about entry point ?

You can use ts or js, it does not matter as module bundler will assign each file to it's corresponding plugin to handle based on the Webpack configuration during bundling.

Can I have all my files in *.ts format or does the entry point need to be a javascript file?...

Yes, you can have all files in .ts. You may need .tsx if you have jsx code.

I've heard that I should compile my code for commonjs as well as esnext...

Yes, it will affect the user as their browser can be old and will not support latest code.

The library I'm writing depends on React but it won't have any jsx/tsx files...

Do you have jsx code?, if yes then you will need this.

Note: If your full code is in typescript, you do not need babel, you can simply use ts-loader following below link.

You may want to follow this simple Webpack config for typescript - https://webpack.js.org/guides/typescript/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1