kit icon indicating copy to clipboard operation
kit copied to clipboard

Can't import from svelte/compiler after Svelte 4 upgrade - build fails with "Cannot find module '../data/patch.json'" error

Open rmunn opened this issue 1 year ago • 10 comments

Describe the bug

After upgrading a Svelte-Kit project to Svelte 4, it becomes impossible to build the project if you have imported anything from svelte/compiler. The result is an error about "Cannot find module '../data/patch.json'". See below for reproduction steps; to my surprise, the minimal repro involves adding just one line of code to a freshly-created skeleton Svelte-Kit project using Svelte 4.

This is blocking us from upgrading our project to Svelte 4 as we use the svelte/compiler package in one part of our code. We could rewrite that part of the code at considerable effort, but I'd rather just get the build error resolved.

Reproduction

  1. pnpm create svelte@next
  2. Choose skeleton project, answer No to everything else.
  3. pnpm add svelte@4 @sveltejs/[email protected] to upgrade to Svelte 4
  4. pnpm i (not strictly necessary as pnpm add will take care of it)
  5. Create src/routes/+server.js containing just one line, import { compile } from 'svelte/compiler';
  6. pnpm run build
  7. Build fails with Error: Cannot find module '../data/patch.json'

Logs

> [email protected] build /home/rmunn/code/svelte-compiler-repro
> vite build


vite v4.4.9 building SSR bundle for production...
✓ 1253 modules transformed.

node:internal/event_target:912
  process.nextTick(() => { throw err; });
                           ^
Error: Cannot find module '../data/patch.json'
Require stack:
- /home/rmunn/code/svelte-compiler-repro/.svelte-kit/output/server/entries/endpoints/_server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at file:///home/rmunn/code/svelte-compiler-repro/.svelte-kit/output/server/entries/endpoints/_server.js:11564:15
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async analyse (file:///home/rmunn/code/svelte-compiler-repro/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@sveltejs/kit/src/core/postbuild/analyse.js:83:16)
    at async MessagePort.<anonymous> (file:///home/rmunn/code/svelte-compiler-repro/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@sveltejs/kit/src/utils/fork.js:22:16)
Emitted 'error' event on Worker instance at:
    at Worker.[kOnErrorMessage] (node:internal/worker:289:10)
    at Worker.[kOnMessage] (node:internal/worker:300:37)
    at MessagePort.<anonymous> (node:internal/worker:201:57)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:643:20)
    at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/rmunn/code/svelte-compiler-repro/.svelte-kit/output/server/entries/endpoints/_server.js'
  ]
}
 ELIFECYCLE  Command failed with exit code 1.

System Info

System:
    OS: Linux 5.15 Linux Mint 21 (Vanessa)
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 14.68 GB / 62.56 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v16.16.0/bin/yarn
    npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm
    pnpm: 8.6.7 - ~/.local/share/pnpm/pnpm
  Browsers:
    Chromium: 117.0.5938.62
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0-next.90 => 1.0.3 
    @sveltejs/kit: ^1.25.1 => 1.25.1 
    svelte: ^4.2.1 => 4.2.1 
    vite: ^4.0.0 => 4.4.9

Severity

blocking an upgrade

Additional Information

The ../data/patch.json code in question comes from css-tree, in ./node_modules/.pnpm/[email protected]/node_modules/css-tree/lib/data-patch.js. It contains:

import { createRequire } from 'module';

const require = createRequire(import.meta.url);
const patch = require('../data/patch.json');

export default patch;

That code ends up bundled into the _server.js file looking something like this:

const createSyntax$1 = (config) => createSyntax(mix({}, config));
const require$2 = createRequire(import.meta.url);
const patch = require$2("../data/patch.json");
const require$1 = createRequire(import.meta.url);
const mdnAtrules = require$1("mdn-data/css/at-rules.json");
const mdnProperties = require$1("mdn-data/css/properties.json");
const mdnSyntaxes = require$1("mdn-data/css/syntaxes.json");

The relative path in the require call is not being adjusted by the Vite bundling process, so it fails because the current working directory is no longer deep inside the css-tree source (where the data/patch.json file could be found) but rather at the root of the Svelte-Kit project's repo.

rmunn avatar Sep 28 '23 06:09 rmunn

Since the reproduction involves creating a fresh skeleton project, running one pnpm command, and then addding a single line of code, which takes less than a minute to do, it seems silly to create a repro repo that will be around forever with just a single line of code difference from the skeleton Svelte-Kit project. But if that's required, I'll create one.

rmunn avatar Sep 28 '23 06:09 rmunn

Assuming this is the same issue, @gtm-nayan gave a workaround here: https://github.com/sveltejs/svelte/issues/9288#issuecomment-1748034687

geoffrich avatar Oct 06 '23 15:10 geoffrich

Thanks, I'm not totally sure how his code was suppoed to work. But this worked for me:

{
  resolveId(id: string): string | undefined {
    if (id === 'css-tree') {
      return './node_modules/css-tree/dist/csstree.esm.js';
    }
  }
},

hahn-kev avatar Oct 09 '23 06:10 hahn-kev

I resolved this by installing:

npm install mdn-data

sunnysideup avatar Dec 08 '23 00:12 sunnysideup

I'm using Rollup to bundle our code, which uses svelte/compiler, importing it with:

import { compile } from 'svelte/compiler';

Before bundling, everything works fine. But after it, we get the same error informed by OP:

Error: Cannot find module '../data/patch.json'

Update: The error happens both when using npm or pnpm. I even reinstalled everything from scratch with npm only, but the error persists.

Rollup fix Do someone knows how to apply the suggested fix on Rollup config?

paulocoghi avatar Dec 14 '23 11:12 paulocoghi

I found a solution for anyone using Rollup.

1. Install css-tree and @rollup/plugin-virtual on your dependencies (or devDependencies, if you will)

2. On your configuration file for Rollup, add css-tree as a virtual package before every other plugin:

import virtual          from '@rollup/plugin-virtual';
// ...
import { readFileSync } from 'fs';

export default {
	input: 'your_input_here.js',

	output: {
		file: 'your_output_here.js'
		// ...
		// ...
	},

	plugins: [
		virtual({ 'css-tree': readFileSync('./node_modules/css-tree/dist/csstree.esm.js', 'utf8') }),
		// ...
	]
};

paulocoghi avatar Dec 14 '23 15:12 paulocoghi

FWIW the mdsvex plugin also has a compile export that seems to also trigger this issue as well and doing the workarounds for css-tree do not work even though css-tree is in the tree of dependencies and the same code is output in the built app.

stearnsbq-aem avatar Feb 09 '24 18:02 stearnsbq-aem

I ran into this same error message while using a package that relies on svelte/compiler in server-side code under adapter-node, and was able to solve it by having rollup treat css-tree as an external dependency. Details/snippets in this issue comment. @stearnsbq-aem I'm curious to know whether this fix addresses your issue with mdsvex since I'm planning to use that soon...

aaronjbecker avatar Feb 28 '24 16:02 aaronjbecker

FWIW the mdsvex plugin also has a compile export that seems to also trigger this issue as well and doing the workarounds for css-tree do not work even though css-tree is in the tree of dependencies and the same code is output in the built app.

Yup. Ran into this as well.

vlimki avatar Aug 04 '24 16:08 vlimki

In case someone is running into the same issue with mdsvex, I solved the problem by simply setting mdsvex as a non-dev dependency.

vlimki avatar Aug 04 '24 16:08 vlimki