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

Convoluted way of using @svelte/package inside a monorepo #11866

Open
andresgutgon opened this issue Feb 17, 2024 · 3 comments
Open

Convoluted way of using @svelte/package inside a monorepo #11866

andresgutgon opened this issue Feb 17, 2024 · 3 comments
Labels
pkg:svelte-package Issues related to svelte-package

Comments

@andresgutgon
Copy link

andresgutgon commented Feb 17, 2024

Describe the problem

πŸ‘‹ Hi, how are you? πŸ˜ƒ I hope everything is all right.

We are developing a monorepo with pnpm workspaces and Turbo repo.

This is our monorepo file structure

/
└── fun-with-monorepo
    β”œβ”€β”€ apps
    β”‚   └── server (SvelteKit main app
    └── packages
        └── svelte-ui

NOTE: apps/server and packages/svelte-ui both are SvelteKit apps.

We have several goals with @fun-with-monorepo/svelte-ui package

  1. We want to have a great dev experience in the monorepo by not having a build
    step inside this package and let our main app in ./apps/server compile the
    .svelte and .ts files in this package. Way faster, feels like developing
    in the app.
  2. We want to have the easiest Storybook setup. And that's by being this package
    another SveltKit app.
  3. We want to use the official way in Svelte to author npm packages. And that's by
    using their packaging npm module called @svelte/package.
  4. We want our package published in npmjs.com

So as you can points (1) and (2) are about our dev experience as monorepo
developers. And points (3) and (4) are about shipping this package as an npmjs
UI library other people can use.

The problem?

Right, the problem. Here starts the funny part. Before 2023 svelte-package was
modifing your package.json and Svelte maintainers felt (I think) that was not a
good idea (and I agree). Rich Harris can explain better than I do. But long story short we want 2 different things while we're developing this package inside the monorepo and when we build it for others to use.

The difference resides in the package.json exports field. For comparison
here is what we want in dev and production build:

Development

// package.json
"exports": {
  ".": {
    "types": "./src/lib/index.ts",
    "import": "./src/lib/index.ts"
  }
}

Production

// package.json
"exports": {
  ".": {
    "types": "./dist/index.d.ts",
    "import": "./dist/index.js"
  }
}

As you can see in dev we point directly to the .src/lib source code because we
know our Storybook or our other SveltKit app (the main app) in ./apps/server are doing
the work of transpiling all the *.{ts,svelte} files. Nice!

On the other hand on production we want to point exports field in
package.json to ./dist folder that was produced by svelte-package.

Describe the proposed solution

No solution, at least nothing I can think that can be applied. But I'm here to listen to alternatives. : )

Alternatives considered

Weeell, as always with code is all about trade-offs. We would't had this problem
if this package was not a SvelteKit app and we didn't use svelte-package. We
could do our own rollup plugin and ship it this way. But I think that by staying with the official
way we're more aligned with svelte ecosystem.

Sooo, what's the solution?

The solution is to put in git the development version of exports pointing to ./src/lib so this way dev experience is fantastic. And when we do the building we modify on runtime the package.json with a prebuid script that you can see in this same folder. This script is used in the scripts field in the package.json like this:

// package.json
"scripts": {
  "build:vite": "vite build",
  "prebuild": "node ./scripts/hack-svelte-package/prebuild.js",
  "buildAndPackage": "pnpm run build:vite && pnpm run package",
  "build": "pnpm run prebuild && pnpm run buildAndPackage",
}

All is perfect for one little thing. After we run pnpm build our package.json gets modified

    "./*": {
-      "types": "./src/lib/ui/*/index.ts",
-      "import": "./src/lib/ui/*/index.ts",
-      "svelte": "./src/lib/ui/*/index.svelte"
+      "types": "./dist/ui/*/index.d.ts",
+      "svelte": "./dist/ui/*/index.js"
     }

And this is bad, very bad. So the solution for this is to check if exports
field contains ./dist in it. It never should. We acomplish that with a custom
eslint rule you can find in ./eslint-local-rules.cjs

image

I hope you enjoyed as much as I did this little fairy tale 😹

Importance

would make my life easier

Additional Information

I'm not sure if the goal of svelte-package is to place nice with monorepos. I'm not asking for an official solution. I'm just adding here my 2cents to see if someone have a better solution of if this solution can help others.

@andresgutgon andresgutgon changed the title Convoluted way of using svelte-package inside a monorepo Convoluted way of using @svelte/package inside a monorepo Feb 17, 2024
@sastan
Copy link
Contributor

sastan commented Mar 12, 2024

If you are using pnpm you can use publishConfig. It works quite well but is repetitive:

"exports": {
  ".": {
    "types": "./src/lib/index.ts",
    "import": "./src/lib/index.ts"
  }
},
"publishConfig": {
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js"
    }
  }
}

Documentation: https://pnpm.io/package_json#publishconfig

@andresgutgon
Copy link
Author

We ended for now running the build command on watch mode. I think is not ideal but it works

@andresgutgon
Copy link
Author

publishConfig has the problem that it fails if the paths defined in normal exports are using alias like $lib. In the package using this lib $lib can't be found

@benmccann benmccann added the pkg:svelte-package Issues related to svelte-package label Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:svelte-package Issues related to svelte-package
Projects
None yet
Development

No branches or pull requests

3 participants