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

Build CJS files via Rollup #7037

Merged
merged 37 commits into from Jul 13, 2023
Merged

Build CJS files via Rollup #7037

merged 37 commits into from Jul 13, 2023

Conversation

ybiquitous
Copy link
Member

@ybiquitous ybiquitous commented Jul 3, 2023

Which issue, if any, is this issue related to?

Ref #5291

Is there anything in the PR that needs further explanation?

Steps for this PR:

  1. Run npm i -D rollup
  2. Create rollup.config.mjs
  3. Rewrite .js to .mjs in ESM
    • Note that this PR includes just a few .mjs. Following-up PRs will gradually migrate .js files to ESM.

Discussion points:

  • Should we commit .cjs files? => Yes.

See https://rollupjs.org/


Note: This PR is still a draft, but I welcome any feedback. 👍🏼

mattxwang and others added 4 commits July 3, 2023 20:39
I'll quickly explain the methodology for this PR:

1. remove each `lib/rules/*` for each deprecated test
2. remove each (now invalid) path from `lib/rules/index.js`
3. fix all broken tests, which fall into one of several categories:
    - tests that use a deprecated rule as an arbitrary rule; to resolve this, I just picked a different rule (usually `color-named` for `color-hex-case` and `number-max-precision` for `indentation`)
        - one of these is about a custom plugin, so I've rewritten the plugin
    - tests that are *about* deprecated rules; I added a `.skip` (have left comments in the review)
    - fs tests that use deprecated rules; I removed these from the config, then updated the snapshot.
      - the zen garden one doesn't work "out of the box" anymore, i.e. the snapshot has nontrivially changed because of indentation/spacing rules
    - `indentation`-specific behaviour (it being last); I deleted these!
4. remove all documentation related to removed rules (mostly `indentation`)
5. remove all unused utilities (via code coverage, not manual inspection)
Ref: #6979 (comment)

Re-running the script indicates no newly-unused files:

```sh
$ node scripts/find-unused-modules.mjs
```
Node.js 16.13.0 is the first version of Node.js 16.x LTS series.
See https://nodejs.org/en/blog/release/v16.13.0
@changeset-bot
Copy link

changeset-bot bot commented Jul 3, 2023

⚠️ No Changeset found

Latest commit: e78b70f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ybiquitous ybiquitous force-pushed the esm-rollup branch 2 times, most recently from 0c9dae3 to 188b9f6 Compare July 3, 2023 14:01
package.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
@romainmenke
Copy link
Member

Should we commit .cjs files?

For everything under @csstools/postcss-plugins we use this approach :

  • every build output is committed
  • CI rebuilds changed plugins and fails if the build output in git doesn't match a fresh build

this steps are fairly complicated because it is a monorepo housing many different packages

We switched to this strategy because building every plugin took to long and we didn't want CI duration to be a factor when deciding to create something new.

In practice we found that it is very rare that more than one person is changing the same plugin at the same time. So we rarely have conflicts in build outputs. I can imagine that the same is true for Stylelint rules.

We also added some git attributes to make it easier to resolve conflicts : https://github.com/csstools/postcss-plugins/blob/main/.gitattributes#L3-L6

When there is a conflict it will always result in a broken build output file, but that is fine.
This allows us to stay focused on the merge conflicts in the source files.
After resolving those we rebuild and commit the new outputs.

)

`mergeTestDescriptions()` is used by deprecated rules.
So I've created this commit from the `v16` branch, instead of the `main` branch.

This change enables the `esModuleInterop` flag to prevent the following TypeScript error:

```
lib/testUtils/mergeTestDescriptions.mjs:1:8 - error TS1259: Module '"/Users/masafumi.koba/git/stylelint/stylelint/node_modules/deepmerge/index"' can only be default-imported using the 'esModuleInterop' flag

1 import merge from 'deepmerge';
         ~~~~~

  node_modules/deepmerge/index.d.ts:20:1
    20 export = deepmerge;
       ~~~~~~~~~~~~~~~~~~~
    This module is declared with 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
```
@ybiquitous
Copy link
Member Author

@romainmenke Thanks for providing the actual example. There are many pros and cons here.

Checking built CJS files' validity on CI sounds good. 👍🏼

I'm concerned about verbose Git commit history. 🤔

@ybiquitous
Copy link
Member Author

I found an advantage in committing .cjs files. Committed .cjs enables people to install stylelint from GitHub, for example:

npm install github:stylelint/stylelint

The second advantage is that we can easily compare .mjs and .cjs without building, for example, on GitHub. I'm leaning towards committing .cjs now, though we can go back before releasing v16.

scripts/build-check.mjs Outdated Show resolved Hide resolved
@ybiquitous ybiquitous marked this pull request as ready for review July 4, 2023 14:16
@ybiquitous
Copy link
Member Author

Now ready for review!

package.json Show resolved Hide resolved
I'll quickly explain the methodology for this PR:

1. remove each `lib/rules/*` for each deprecated test
2. remove each (now invalid) path from `lib/rules/index.js`
3. fix all broken tests, which fall into one of several categories:
    - tests that use a deprecated rule as an arbitrary rule; to resolve this, I just picked a different rule (usually `color-named` for `color-hex-case` and `number-max-precision` for `indentation`)
        - one of these is about a custom plugin, so I've rewritten the plugin
    - tests that are *about* deprecated rules; I added a `.skip` (have left comments in the review)
    - fs tests that use deprecated rules; I removed these from the config, then updated the snapshot.
      - the zen garden one doesn't work "out of the box" anymore, i.e. the snapshot has nontrivially changed because of indentation/spacing rules
    - `indentation`-specific behaviour (it being last); I deleted these!
4. remove all documentation related to removed rules (mostly `indentation`)
5. remove all unused utilities (via code coverage, not manual inspection)
Ref: #6979 (comment)

Re-running the script indicates no newly-unused files:

```sh
$ node scripts/find-unused-modules.mjs
```
ybiquitous and others added 7 commits July 8, 2023 23:04
To prevent `npm run build` for consumers.
I'll quickly explain the methodology for this PR:

1. remove each `lib/rules/*` for each deprecated test
2. remove each (now invalid) path from `lib/rules/index.js`
3. fix all broken tests, which fall into one of several categories:
    - tests that use a deprecated rule as an arbitrary rule; to resolve this, I just picked a different rule (usually `color-named` for `color-hex-case` and `number-max-precision` for `indentation`)
        - one of these is about a custom plugin, so I've rewritten the plugin
    - tests that are *about* deprecated rules; I added a `.skip` (have left comments in the review)
    - fs tests that use deprecated rules; I removed these from the config, then updated the snapshot.
      - the zen garden one doesn't work "out of the box" anymore, i.e. the snapshot has nontrivially changed because of indentation/spacing rules
    - `indentation`-specific behaviour (it being last); I deleted these!
4. remove all documentation related to removed rules (mostly `indentation`)
5. remove all unused utilities (via code coverage, not manual inspection)
Ref: #6979 (comment)

Re-running the script indicates no newly-unused files:

```sh
$ node scripts/find-unused-modules.mjs
```
Node.js 16.13.0 is the first version of Node.js 16.x LTS series.
See https://nodejs.org/en/blog/release/v16.13.0
)

`mergeTestDescriptions()` is used by deprecated rules.
So I've created this commit from the `v16` branch, instead of the `main` branch.

This change enables the `esModuleInterop` flag to prevent the following TypeScript error:

```
lib/testUtils/mergeTestDescriptions.mjs:1:8 - error TS1259: Module '"/Users/masafumi.koba/git/stylelint/stylelint/node_modules/deepmerge/index"' can only be default-imported using the 'esModuleInterop' flag

1 import merge from 'deepmerge';
         ~~~~~

  node_modules/deepmerge/index.d.ts:20:1
    20 export = deepmerge;
       ~~~~~~~~~~~~~~~~~~~
    This module is declared with 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
```
@jeddy3
Copy link
Member

jeddy3 commented Jul 9, 2023

@ybiquitous Thank you for already moving the migration to ESM along so far!

I've been catching up on the discussions in #5291, and I wanted to check how we feel about #5291 (comment):

Are you sure it's ok for some plugins to import from the ESM Stylelint modules, and some to require from the CJS ones, at the same time when linting a project occurs? That won't cause problems?

Is there any way for us to test this?

@ybiquitous
Copy link
Member Author

@jeddy3 Good point. I think we should add a system test case to test importing ESM and CJS plugins in one config. For example:

{
	"plugins": ["./plugin.cjs", "./plugin.mjs"],
	"rules": {
		"cjs/foo": true,
		"esm/foo": true
	}
}

However, please note that this case should fail now since the current Stylelint supports only require(), not import():

pluginImport = require(pluginLookup);

I think we need to change require() to import() (dynamic import) to support both ESM and CJS. This means we need to introduce a Promise-based API, keeping backward compatibility as possible.

Any thoughts?

@jeddy3
Copy link
Member

jeddy3 commented Jul 10, 2023

I think we need to change require() to import() (dynamic import) to support both ESM and CJS. This means we need to introduce a Promise-based API, keeping backward compatibility as possible.

I believe so. We can see if keeping backward compatibility is possible with our resources.

How do we move forward with this pull request, e.g. shall we merge so we can keep moving forward with trying dynamic imports to uncover any potential issues?

(I'm going offline for a week for a festival. I've approved the PR in case this is the route we want to go down, and I don't want to block you.)

Copy link
Member

@jeddy3 jeddy3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks again for driving the migration to ESM forward!

@ybiquitous
Copy link
Member Author

How do we move forward with this pull request, e.g. shall we merge so we can keep moving forward with trying dynamic imports to uncover any potential issues?

I suggest gradually rewriting the current code to ESM to make each PR easier to review. I guess the most difficult part may be around importing (e.g. require() or import-lazy)

@ybiquitous ybiquitous merged commit e0b80ec into v16 Jul 13, 2023
15 checks passed
@ybiquitous ybiquitous deleted the esm-rollup branch July 13, 2023 13:01
ybiquitous added a commit that referenced this pull request Jul 20, 2023
ybiquitous added a commit that referenced this pull request Jul 24, 2023
ybiquitous added a commit that referenced this pull request Jul 25, 2023
ybiquitous added a commit that referenced this pull request Jul 26, 2023
ybiquitous added a commit that referenced this pull request Jul 26, 2023
ybiquitous added a commit that referenced this pull request Jul 27, 2023
ybiquitous added a commit that referenced this pull request Aug 12, 2023
ybiquitous added a commit that referenced this pull request Aug 14, 2023
ybiquitous added a commit that referenced this pull request Aug 27, 2023
ybiquitous added a commit that referenced this pull request Aug 27, 2023
ybiquitous added a commit that referenced this pull request Sep 28, 2023
ybiquitous added a commit that referenced this pull request Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants