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

[starter-kit] A targeted folder for build artifacts #4619

Open
1 task done
fireflysemantics opened this issue Apr 12, 2024 · 7 comments
Open
1 task done

[starter-kit] A targeted folder for build artifacts #4619

fireflysemantics opened this issue Apr 12, 2024 · 7 comments

Comments

@fireflysemantics
Copy link

fireflysemantics commented Apr 12, 2024

Should this be an RFC?

  • This is not a substantial change

Which package is this a feature request for?

Lit Core (lit / lit-html / lit-element / reactive-element)

Description

It would be nice if all the built lit resources ended up in a target folder. This makes it easier to change the project.json scripts to accomodate changing the element name and also building more than one element within a single lit project.

The docs part of lit takes this approach. This is how the docs:clean script looks.

"docs:clean": "rimraf docs",

Alternatives and Workarounds

The clean scripts deletes built lit resources like this.

 "clean": "rimraf my-element.{d.ts,d.ts.map,js,js.map} test/my-element.{d.ts,d.ts.map,js,js.map} test/my-element_test.{d.ts,d.ts.map,js,js.map}",

And so if we add more elements or change the name my-element we have to modify these scripts.

If the built resources ended up in for example target/main and target/test, then we could just have the clean script delete the content of these folders and it keeps the root folder less "Messy" which I think is an "Aesthetically" pleasing thing ...

@augustjk augustjk changed the title A targeted folder for build artifacts [starter-kit] A targeted folder for build artifacts Apr 12, 2024
@augustjk
Copy link
Member

I think this issue is referring to starter kits, which are currently tailored for authoring and publishing a single component.

We have wanted for a long time to show case different set ups for also authoring a design system (multiple components in a package with interdependencies and styles), and a whole app too (#1929). But project starters end up being very opinionated hard to come up with a one solution fits all. In the end, the user will have to modify the starter kit to fit their use case anyway.

I will add that the reason why we emit the the built artifact to the root directory which could make it look "messy" is that older build tools/bundlers with outdated module resolution works best when the artifact locations in the published package match the hierarchy particularly for sub-modules like if you want to make import 'my-package/components/my-component.js' work. These days it's less of a concern with package exports being more ubiquitous.

@fireflysemantics
Copy link
Author

fireflysemantics commented Apr 12, 2024

@augustjk if I remember correctly the publish script for lit publishes all the contents of the root directory.

One idea would be to ceate a publish directory with all the resources that need to be published.

This way the published directory could also be cleaned with a simple script.

So essentially the build / clean process would be the same for doc, web components, and publishing.

It would also be easier for users to customize the project, because now the root directory is fairly static. This should also simplify the project customization documentation.

@fireflysemantics
Copy link
Author

fireflysemantics commented Apr 13, 2024

Another thought is ... Currently the checksize script looks like this:

    "checksize": "rollup -c ; cat fs-link-preview.bundled.js | gzip -9 | wc -c ; rm fs-link-preview.bundled.js"

It would be nice if it was something more generic like this:

"checksize": "rollup -c ; cat index.bundled.js | gzip -9 | wc -c ; rm index.bundled.js"

And part of this is I was wondering whether the thing that gets published and referenced by external libraries / browsers could index.js that is namespaced under a package directory.

This way the bundle stays generically named, and this would allow for generic named components to be broken out and be independent of the project name space essentially ...

Maybe this is as simple as just making the package.json properties for the module generic:

  "main": "index.bundle.js",
  "module": "index.js",
  "types": "index.d.ts",
  "type": "module",

@fireflysemantics
Copy link
Author

The .gitignore files can also be simplified since it can just ignore a folder instead of top level resources like this.

# top level source
my-element.js
my-element.js.map
my-element.d.ts
my-element.d.ts.map

@justinfagnani
Copy link
Collaborator

I will add that the reason why we emit the the built artifact to the root directory which could make it look "messy" is that older build tools/bundlers with outdated module resolution works best when the artifact locations in the published package match the hierarchy particularly for sub-modules like if you want to make import 'my-package/components/my-component.js' work. These days it's less of a concern with package exports being more ubiquitous.

I want to reiterate that this is why we output top-level build artifacts. Many people did want to make simple imports like:

import 'my-package/components/my-component.js';

It's a pretty fundamental thing with starter kits that they encode a lot of opinions, and that very reasonable people might disagree on those opinions. This is one of those things 🤷

Now maybe package exports are widely supported enough now that we could recommend having a package file layout that differs from the exports layout. That would solve this.

@fireflysemantics
Copy link
Author

fireflysemantics commented Apr 14, 2024

Now maybe package exports are widely supported enough now that we could recommend having a package file layout that differs from the exports layout. That would solve this.

I think if we create a publish directory for all resources published, then ultimately we will end up basically with what we have now. The semantics are all the same with a few exceptions.

  1. We copy all resources that are going to be published into the publish directory. So the publish directory is now essentially the new root directory.
  2. instead of having a specifically named file my-element.ts as a starting point, instead it's called index.ts. That's the starting point. And all resources that are going to be published are imported into index.ts.

This way users do not need to rename anything, if they want to change the file name of the web component.

From the client of a package point of view nothing has changed. Clients are still consuming the element the same way they would consume it before any of these changes would be made.

For users of Lit however it's now much easier to change file names and break out code into their own files, because everything gets imported into index.ts ultimately and only built resources associated with index.ts are named in package.json.

@fireflysemantics
Copy link
Author

Here's how I think the entire thing could be done.

  1. Compile so that all built resources are placed in a build directory.
  2. Refactor package.json export properties like this:
  "main": "index.bundle.js",
  "module": "index.js",
  "types": "index.d.ts",
  "type": "module",
  1. Copy all the resources that were being published at the root level into a publish directory.
  2. When publishing cd into the publish directory and just publish the same way that the project was published before.

And the benefits of this are.

  1. Less refactoring of all the files when changing a file name
  2. It's easier to breakout code into separate files, since index.ts is the only client facing resource and all the other files are hidden behind this entry point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

3 participants