-
Notifications
You must be signed in to change notification settings - Fork 8
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: replace glob-to-regexp
with URLPattern
#392
Changes from 1 commit
2be62fd
a77c45d
b308434
ec13d82
772d075
a74c3ef
cec6b93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,7 +46,7 @@ test('Generates a manifest with display names', () => { | |
} | ||
const manifest = generateManifest({ bundles: [], declarations, functions, internalFunctionConfig }) | ||
|
||
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1/.*/?$' }] | ||
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$' }] | ||
expect(manifest.function_config).toEqual({ | ||
'func-1': { name: 'Display Name' }, | ||
}) | ||
|
@@ -65,7 +65,7 @@ test('Generates a manifest with a generator field', () => { | |
} | ||
const manifest = generateManifest({ bundles: [], declarations, functions, internalFunctionConfig }) | ||
|
||
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1/.*/?$' }] | ||
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$' }] | ||
const expectedFunctionConfig = { 'func-1': { generator: '@netlify/[email protected]' } } | ||
expect(manifest.routes).toEqual(expectedRoutes) | ||
expect(manifest.function_config).toEqual(expectedFunctionConfig) | ||
|
@@ -79,13 +79,13 @@ test('Generates a manifest with excluded paths and patterns', () => { | |
] | ||
const declarations: Declaration[] = [ | ||
{ function: 'func-1', path: '/f1/*', excludedPath: '/f1/exclude' }, | ||
{ function: 'func-2', pattern: '^/f2/.*/?$', excludedPattern: '^/f2/exclude$' }, | ||
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$', excludedPattern: '^/f2/exclude$' }, | ||
{ function: 'func-3', path: '/*', excludedPath: '/**/*.html' }, | ||
] | ||
const manifest = generateManifest({ bundles: [], declarations, functions }) | ||
const expectedRoutes = [ | ||
{ function: 'func-1', pattern: '^/f1/.*/?$' }, | ||
{ function: 'func-2', pattern: '^/f2/.*/?$' }, | ||
{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$' }, | ||
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' }, | ||
{ function: 'func-3', pattern: '^/.*/?$' }, | ||
] | ||
|
||
|
@@ -127,7 +127,7 @@ test('Filters out internal in-source configurations in user created functions', | |
] | ||
const declarations: Declaration[] = [ | ||
{ function: 'func-1', path: '/f1/*' }, | ||
{ function: 'func-2', pattern: '^/f2/.*/?$' }, | ||
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' }, | ||
] | ||
const userFunctionConfig: Record<string, FunctionConfig> = { | ||
'func-1': { | ||
|
@@ -178,7 +178,7 @@ test('Includes failure modes in manifest', () => { | |
] | ||
const declarations: Declaration[] = [ | ||
{ function: 'func-1', path: '/f1/*' }, | ||
{ function: 'func-2', pattern: '^/f2/.*/?$' }, | ||
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' }, | ||
] | ||
const userFunctionConfig: Record<string, FunctionConfig> = { | ||
'func-1': { | ||
|
@@ -288,8 +288,8 @@ test('Generates a manifest with layers', () => { | |
{ function: 'func-2', path: '/f2/*' }, | ||
] | ||
const expectedRoutes = [ | ||
{ function: 'func-1', pattern: '^/f1/.*/?$' }, | ||
{ function: 'func-2', pattern: '^/f2/.*/?$' }, | ||
{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$' }, | ||
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' }, | ||
] | ||
const layers = [ | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { URLPattern } from 'urlpattern-polyfill' | ||
|
||
export class ExtendedURLPattern extends URLPattern { | ||
// @ts-expect-error Internal property that the underlying class is using but | ||
// not exposing. | ||
regexp: Record<string, RegExp> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good idea. This will most probably not be available once this is available in Node.js natively. Also looking at the docs of how There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The mdn docs mention this library: https://github.com/pillarjs/path-to-regexp maybe we should use this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I know that this property will not be exposed by the native
The native
That is a user-defined library though, not a standard. The whole point of this is to say that the path expressions you write when defining edge functions use the Using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, up to you. I personally feel this is a terrible idea to rely on the internals and implementation details of other packages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate that, but can you help find a better idea? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I share the sentiment of this feeling "bad", but I think it's an example of us knowing the rules enough that we're allowed to break them. Since we're using a polyfill, the underlying implementation won't depend on the runtime, and since we have tests we'll notice when a change in the polyfill breaks this. I think it's fine - and if we find problems, as a last resort we can still reimplement the spec ourselves. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My concern here is that we're opening ourselves to the possibility of the internals of the polyfill changing, as it's not a public API. At the very least we should pin an exact version, but personally I'd be more inclined to say we should vendor the polyfill and add the subclass to our fork. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Totally. I actually meant to do this but ended up forgetting about it. Done in b308434.
If the internals change and the property we're using disappears or gets renamed, our own tests would catch it. I'm not opposed to using our own fork if this makes people more comfortable — in fact, we do already have a fork, which I created in order to push a change upstream. But if we go down that path, I would rather keep it on its own repo from where we can easily merge upstream changes, run the tests, etc. Not sure what we get by vendoring it in with Edge Bundler? |
||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked the impact of changing from
/.*
to(?:/(.*))
with this go benchmark:It's naïve, so i'm not sure how much we can trust it, but it shows that the group has a slight negative impact on performance (while having the same semantics, I think):
This is a ~17% hit in compile time and ~5% in matching time.
Is there an easy way for us to prevent this change from adding capture groups to the output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove capturing groups ourselves, since we're parsing the regular expression into an AST and transforming it. But I don't think that's a huge priority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay 👍 Maybe we can capture this in an issue, so we don't forget about it.