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

feat: implement rules config field #530

Merged
merged 1 commit into from
Feb 28, 2022
Merged

Conversation

threepointone
Copy link
Contributor

This implements the top level rules configuration field. It lets you specify transport rules for non-js modules. For example, you can specify *.md files to be included as a text file with -

[[rules]]
{type = "Text", globs = ["**/*.md"]}

We also include a default ruleset -

  { type: "Text", globs: ["**/*.txt", "**/*.html", "**/*.pem"] },
  { type: "Data", globs: ["**/*.bin"] },
  { type: "CompiledWasm", globs: ["**/*.wasm"] },

More info at https://developers.cloudflare.com/workers/cli-wrangler/configuration/#build.

Known issues -

  • non-wasm module types do not work in --local mode
  • Data type does not work in service worker format, in either mode

@github-actions
Copy link
Contributor

github-actions bot commented Feb 28, 2022

A wrangler prerelease is available for testing. You can install this latest build in your project with:

npm install --save-dev https://prerelease-registry.developers.workers.dev/runs/1912742590/npm-package-wrangler-530

You can reference the automatically updated head of this PR with:

npm install --save-dev https://prerelease-registry.developers.workers.dev/prs/530/npm-package-wrangler-530

Or you can use npx with this latest build directly:

npx https://prerelease-registry.developers.workers.dev/runs/1912742590/npm-package-wrangler-530 dev path/to/script.js

@threepointone
Copy link
Contributor Author

Why didn't the changeset bot drop a comment here? 🤔 I'll investigate later, unless someone else has an idea

@changeset-bot
Copy link

changeset-bot bot commented Feb 28, 2022

🦋 Changeset detected

Latest commit: 9cfaec8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
wrangler Patch

Not sure what this means? Click here to learn what changesets are.

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

Copy link
Contributor

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

I left a bunch of comments, but no blockers.

Comment on lines +2057 to +2058
{ type: "Text", globs: ["**/*.file"], fallthrough: true },
{ type: "Text", globs: ["**/*.other"], fallthrough: true },
Copy link
Contributor

Choose a reason for hiding this comment

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

Not related to this PR, but I don't understand how this is different to:

{ type: "Text", globs: ["**/*.file", **/*.other"] },

and if so, what the point of fallthrough is?
🤔

Copy link
Contributor

@petebacondarwin petebacondarwin Feb 28, 2022

Choose a reason for hiding this comment

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

If it is not useful (and just adds unnecessary complexity), how about we just don't support fallthrough as a breaking change?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, OK. So it seems that this is used to allow custom rules to fallback to the DEFAULT_MODULE_RULES...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or any rule that follows. It's a weird one, but I have to preserve the behaviour.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, but apart from the default ones, the developer of the worker has full control over this list, so they could just put all the globs that they want to match into a single rule for a particular type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct, but that would be a breaking change. I didn't want to introduce that in this PR. Happy to do so in a subsequent one.

Comment on lines 2109 to 2117
let err: Error | undefined;
try {
await runWrangler("publish index.js");
} catch (e) {
err = e as Error;
}
expect(err?.message).toMatch(
`The file ./other.other matched a module rule in your configuration ({"type":"Text","globs":["**/*.other"]}), but was ignored because a previous rule with the same type had \`fallthrough = false\`.`
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use:

await expect(runWrangler("publish index.js")).rejects.toThrowError(...);

(or similar but with an inline snapshot)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because the full error contains a file path specific to the machine (so in my case, it contained my home dir etc) and I needed to match only with part of the error.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. So I tried rejects.toThrowError() with the same string you provide here and it worked; so I am not sure what the problem is.

To be clear I tried:

      await expect(runWrangler("publish index.js")).rejects.toThrowError(
        `The file ./other.other matched a module rule in your configuration ({"type":"Text","globs":["**/*.other"]}), but was ignored because a previous rule with the same type had \`fallthrough = false\`.`
      );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh damn you're right, I was trying toMatchInlineSnapshot

fs.writeFileSync("./other.other", "SOME OTHER TEXT CONTENT");

// We throw an error when we come across a file that matched a rule
// but was skipped because of faullthrough = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// but was skipped because of faullthrough = false
// but was skipped because of fallthrough = false

fs.writeFileSync("./other.other", "SOME OTHER TEXT CONTENT");

// We throw an error when we come across a file that matched a rule
// but was skipped because of faullthrough = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// but was skipped because of faullthrough = false
// but was skipped because of fallthrough = false

Comment on lines +361 to +362
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.concat(DEFAULT_MODULE_RULES!)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good reason for the Config not to have unnecessary optional properties.

} else {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
} else {
}
}

index++;
}

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Copy link
Contributor

Choose a reason for hiding this comment

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

😢

.update(fileContent)
.digest("hex");
const fileName = `${fileHash}-${path.basename(args.path)}`;
rules?.forEach((rule) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

😭

// with an underscore.
// TODO: what of "Data"?
contents: `export default ${args.path.replace(
/[^a-zA-Z0-9_$]/g,
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to ensure that the first character is not a number?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's always a relative path, so I didn't bother (unless I'm wrong?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean that these paths always start with ./, which will be converted to __?

args.path
} matched a module rule in your configuration (${JSON.stringify(
rule
)}), but was ignored because a previous rule with the same type had \`fallthrough = false\`.`
Copy link
Contributor

Choose a reason for hiding this comment

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

Strictly, I think it is ignored because a previous rule did not have fallthrough = true, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, yes.

console.warn(
`Deprecation notice: The \`build.upload.rules\` config field is no longer used, the rules should be specified via the \`rules\` config field. Delete the \`build.upload\` field from the configuration file, and add this:

${TOML.stringify({ rules: config.build.upload.rules })}`
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

This implements the top level `rules` configuration field. It lets you specify transport rules for non-js modules. For example, you can specify `*.md` files to be included as a text file with -

```
[[rules]]
{type = "Text", globs = ["**/*.md"]}
```

We also include a default ruleset -

```
  { type: "Text", globs: ["**/*.txt", "**/*.html"] },
  { type: "Data", globs: ["**/*.bin"] },
  { type: "CompiledWasm", globs: ["**/*.wasm"] },
```

More info at https://developers.cloudflare.com/workers/cli-wrangler/configuration/#build.

Known issues -

- non-wasm module types do not work in `--local` mode
- `Data` type does not work in service worker format, in either mode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants