remix icon indicating copy to clipboard operation
remix copied to clipboard

Cannot use import statement outside a module (in monorepo)

Open ahoyahoy opened this issue 2 years ago • 4 comments

What version of Remix are you using?

latest

Steps to Reproduce

https://github.com/ahoyahoy/remix-super-error

run in root

npm i
npm run dev

open http://localhost:3000 and http://localhost:3008

Expected Behavior

Next.js (port 3000) app works correctly and import Button from UI package.

I want same result in Remix app (without build UI package). Also I want to use same approach with shared tsconfig.

Actual Behavior

Remix app return error SyntaxError: Cannot use import statement outside a module . Also remix always rewrite my tsconfig... which is pretty annoying (https://github.com/remix-run/remix/discussions/3180)

ahoyahoy avatar Sep 19 '22 21:09 ahoyahoy

Something definitely off. I have a remix app in a monorepo with the version 1.6.7 and works perfectly. Upgrading to version 1.7.2 I get this problem as well

lughino avatar Oct 17 '22 22:10 lughino

I have confirmed this is still an issue on 1.7.5

remix has major issues resolving local dependencies in mono repos, i'm not sure if its something to do with the symlinks - but i've been pulling my hair out all day trying to import a TS local library into my Remix app.

Here is another reproduction of this issue

https://github.com/dan-cooke/remix-esbuild-resolve-bug

  1. Run yarn
  2. yarn build --filter remix-example
  3. Inspect the build output

You will see that the ui has not been bundled

var import_react2 = require("@remix-run/react"), import_ui = require("ui"), import_jsx_dev_runtime = require("react/jsx-dev-runtime"), meta = () => ({
  charset: "utf-8",
  title: "New Remix App",
  viewport: "width=device-width,initial-scale=1"
});

And of course if you try to execute this you will get the OP error "Cannot use ipmort statement outside a module"

Because node require will try to require the TS version of the UI module.

This issue makes developing Remix in a monorepo incredibly annoying as you will have to create buildable versions of all your TS libraries and pre-build them before your remix app.

dan-cooke avatar Nov 16 '22 17:11 dan-cooke

Okay I've figured it out.

After digging into the compiler code and finding what I assumed to be a buggy plugin serverBareModulesPlugin, I discovered a hidden (not really I just haven't read the docs in a while) option in the remix config.

serverDependenciesToBundle

You can specify your local modules in here and remix will include them in the bundle.

/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
  ignoredRouteFiles: ["**/.*"],
  // appDirectory: "app",
  // assetsBuildDirectory: "public/build",
  // serverBuildPath: "build/index.js",
+  serverDependenciesToBundle: ["@baggers/ui"],
  // publicPath: "/build/",
};

Brief Explanation

It appears that the serverBareModulesPlugin is marking every module as external, unless it passes certain criteria to be bundled. Which when you think about it - makes a lot of sense. E.g most modules are external unless they start with ./ or /

Here is the line in question. https://github.com/remix-run/remix/blob/main/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts#L123

Hope this helps someone

dan-cooke avatar Nov 16 '22 19:11 dan-cooke

@ahoyahoy Can you give @dan-cooke suggestion a try and see if it fixes your issue? 🙏🏼

machour avatar Jan 22 '23 14:01 machour

This issue has been automatically closed because we haven't received a response from the original author 🙈. This automation helps keep the issue tracker clean from issues that are unactionable. Please reach out if you have more information for us! 🙂

github-actions[bot] avatar Feb 01 '23 15:02 github-actions[bot]