Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Unexpected token with Lerna monorepo -- set internal packages as external #194

Closed
moki opened this issue Nov 16, 2019 · 1 comment
Labels
kind: support Asking for support with something or a specific use case topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc)

Comments

@moki
Copy link

moki commented Nov 16, 2019

Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)

Versions

  • typescript: "^3.6.4"
  • rollup: "^1.23.1"
  • rollup-plugin-typescript2: "^0.25.2"

rollup.config.js

/* eslint-env node */

import { existsSync } from "fs";

import typescript from "rollup-plugin-typescript2";
import livereload from "rollup-plugin-livereload";
import { terser } from "rollup-plugin-terser";
import postcss from "rollup-plugin-postcss";
import serve from "rollup-plugin-serve";
import json from "rollup-plugin-json";
import __typescript from "typescript";

import autoprefixer from "autoprefixer";
import cssnano from "cssnano";

/* Build Constants */

/* Production build bundles each package with lerna
 * to the <BUILD_DIR> subfolder inside each corresponding <packages/**> package folder.
 *
 * Development build bundles story assets as monolith application
 * in the watch mode.
 * Serves it @DEV_SERVER_HOST:DEV_SERVER_PORT with live reload.
 */

/*
if (process.env.LERNA_PACKAGE_NAME === "@moki.codes/mokui-header")
        process.exit(0);
*/

const PRODUCTION = process.env.NODE_ENV === "production";

/* Do not attempt to bundle package if it doesn't export assets */
if (PRODUCTION && !existsSync(process.cwd() + "/index.ts")) {
        process.exit();
}

const DEV_SERVER_HOST = "localhost";
const DEV_SERVER_PORT = 3000;
const STORY_DIR = "stories/";

const BUILD_DIR =
        PRODUCTION && process.env.LERNA_PACKAGE_NAME
                ? "dist/"
                : `${STORY_DIR}dist`;

const pkg =
        PRODUCTION &&
        process.env.LERNA_PACKAGE_NAME &&
        require(`${process.env.LERNA_PACKAGE_NAME}/package.json`);

const pkgname = ({ name }) => name;

const stripscope = name => name.slice(name.lastIndexOf("/") + 1);

const _input = () =>
        PRODUCTION
                ? {
                          [stripscope(pkgname(pkg))]: "index.ts"
                  }
                : [`${STORY_DIR}index.ts`];

const _output = () =>
        PRODUCTION
                ? [
                          /*
                          {
                                  dir: `${BUILD_DIR}cjs`,
                                  format: "cjs",
                                  sourcemap: false
                          },
                          */
                          {
                                  dir: `${BUILD_DIR}esm`,
                                  format: "esm",
                                  sourcemap: false
                          }
                  ]
                : { dir: BUILD_DIR, format: "esm", sourcemap: false };

const _serve = () =>
        !PRODUCTION
                ? serve({
                          headers: {
                                  "Access-Control-Allow-Origin": "*"
                          },
                          contentBase: [STORY_DIR, BUILD_DIR],
                          host: DEV_SERVER_HOST,
                          port: DEV_SERVER_PORT
                  })
                : "";

const _livereload = () =>
        !PRODUCTION
                ? livereload({
                          watch: [STORY_DIR, BUILD_DIR]
                  })
                : "";

const _postcss = () =>
        postcss({
                plugins: [autoprefixer(), cssnano()],
                extensions: [".css"],
                ...(PRODUCTION
                        ? {
                                  extract: `${BUILD_DIR +
                                          stripscope(pkgname(pkg))}.css`,
                                  inject: false
                          }
                        : {
                                  /*
                                  extract: `${BUILD_DIR}/index.css`,
                                  inject: false
                                  */
                                  extract: false,
                                  inject: true
                          })
        });

const _typescript = () =>
        typescript({
                tsconfig: "tsconfig.json",
                /* verbosity: 3, */
                clean: true,
                typescript: __typescript
        });

const config = {
        input: _input(),
        output: _output(),
        plugins: [
                _typescript(),
                _livereload(),
                _postcss(),
                _serve(),
                // terser(),
                json()
        ]
};

export default config;

tsconfig.json

{
        "compilerOptions": {
                "target": "esnext",
                "module": "commonjs",
                "lib": ["esnext", "dom"],
                "esModuleInterop": true,
                "removeComments": true,
                "moduleResolution": "node",
                "allowSyntheticDefaultImports": true,
                "isolatedModules": true,
                "sourceMap": true
        }
}

plugin output with verbosity 3

lerna ERR! rollup --config ../../rollup.config.js stderr:
loaded ../../rollup.config.js with warnings
(!) Unused external imports
terser imported from external module 'rollup-plugin-terser' but never used

index.ts → dist/esm...
[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
../mokui-base/component.ts (3:7)
1: const root = Symbol("root");
2: 
3: export type Component<T extends object = {}> = T & {
          ^
4:         [root]: Element;
5:         attach(element: Element): Component<T>;
Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
    at error (/****/****/code/js/mokui/node_modules/rollup/dist/rollup.js:5351:30)
    at Module.error (/****/****/code/js/mokui/node_modules/rollup/dist/rollup.js:9643:9)
    at tryParse (/****/****/code/js/mokui/node_modules/rollup/dist/rollup.js:9552:16)
    at Module.setSource (/****/****/code/js/mokui/node_modules/rollup/dist/rollup.js:9868:33)
    at Promise.resolve.catch.then.then.then (/****/****/code/js/mokui/node_modules/rollup/dist/rollup.js:12148:20)


lerna ERR! rollup --config ../../rollup.config.js exited 1 in '@moki.codes/mokui-header'

I've explained situation in depth there:

https://stackoverflow.com/questions/58891901/building-typescript-error-unexpected-token-note-that-you-need-plugins-to

Basically the reason why i am actually posting this here is that, transpiling typescript directly with tsc goes smoothly and that makes sense because how come typescript would not understand its own constructs like export and type right?

So yeah there is that, @ezolenko if you have any idea what might be going wrong please share them.

also thanks for the plugin! Very convenient thing, hope i will be able to use.

@moki
Copy link
Author

moki commented Nov 17, 2019

I've resolved the issue, in case anyone encounters the same problem, below i am providing solution:

When one attempts to build each separate package inside the monorepo, rollup attempts to resolve @organization/package-name and include it in the build. You don't want that, so to avoid it upon building each package i am parsing package.json, extracting the dependencies field's keys, then to check against them inside the callback one can provide inside rollup config's external field. This will produce the desired outcome.

import json from "rollup-plugin-json";

const pkg = process.env.LERNA_PACKAGE_NAME &&
          require(`${process.env.LERNA_PACKAGE_NAME}/package.json`);

const dependencies = ({ dependencies }) => Object.keys(dependencies || {});

const pkgdependencies = dependencies(pkg);

/* exported rollup configuration */
const config = {
    /* your config goes here... */
    /* id is the source name if list of dependencies includes
     * id source name, then mark it as external,
     */
    external: id => pkgdependencies.includes(id)
};

export default config;

@moki moki closed this as completed Nov 17, 2019
Repository owner deleted a comment Nov 19, 2019
Repository owner deleted a comment Nov 19, 2019
Repository owner deleted a comment Nov 19, 2019
@agilgur5 agilgur5 added scope: upstream Issue in upstream dependency topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc) kind: support Asking for support with something or a specific use case labels Apr 30, 2022
@agilgur5 agilgur5 changed the title Error: Unexpected token (Note that you need plugins to import files that are not JavaScript) Error: Unexpected token with Lerna monorepo May 26, 2022
@agilgur5 agilgur5 changed the title Error: Unexpected token with Lerna monorepo Error: Unexpected token with Lerna monorepo -- set internal packages as external May 26, 2022
@agilgur5 agilgur5 removed the scope: upstream Issue in upstream dependency label May 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case topic: monorepo / symlinks Related to monorepos and/or symlinks (Lerna, Yarn, PNPM, Rush, etc)
Projects
None yet
Development

No branches or pull requests

2 participants