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(resolve)!: allow removing conditions #18395

Merged
merged 22 commits into from
Oct 31, 2024

Conversation

sapphi-red
Copy link
Member

Description

Updates the default conditions / externalConditions and remove the need for overrideConditions and other odd logics.

refs #18016
refs #18332
refs #17326
refs #9860

@sapphi-red sapphi-red added breaking change p3-significant High priority enhancement (priority) feat: environment API Vite Environment API labels Oct 18, 2024
Copy link

stackblitz bot commented Oct 18, 2024

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Comment on lines 1126 to 1129
case 'node':
return !options.webCompatible
case 'browser':
return options.webCompatible
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm using webCompatible here for now. But probably we should do it in the env side. I left this for now to do that when removing the webCompatible flag. I think it would be easier to understand the diff later if it's done at the same time with the browser field.

Copy link
Member Author

Choose a reason for hiding this comment

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

Update: I removed webCompatible in this PR (edcf8f3)

'module',
...options.conditions,
],
const conditions = [...options.conditions, 'require', 'import'].filter(
Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't give users a way to remove require / import as I didn't understand how that would work.

@sapphi-red
Copy link
Member Author

/ecosystem-ci run

@vite-ecosystem-ci
Copy link

📝 Ran ecosystem CI on 15f4875: Open

suite result latest scheduled
astro failure failure
histoire failure success
quasar failure success
remix failure failure
sveltekit failure failure
vike failure failure
vite-plugin-svelte failure success
vitest failure failure

analogjs, ladle, laravel, marko, nuxt, previewjs, qwik, rakkas, redwoodjs, storybook, unocss, vite-environment-examples, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress

@sapphi-red sapphi-red marked this pull request as draft October 22, 2024 10:27
@sapphi-red

This comment was marked as outdated.

@vite-ecosystem-ci

This comment was marked as outdated.

@sapphi-red

This comment was marked as outdated.

@sapphi-red
Copy link
Member Author

sapphi-red commented Oct 23, 2024

If we change the default to ['module', 'browser', 'node', 'production', 'development'] (713cee3), the following CIs fail (#18395 (comment)):

This behavior aligns with resolve.mainFields, but it's not easy to remove default conditions.

import { configDefaults } from 'vite'

const plugin = {
  name: 'remove-conditions',
  config(config) {
    config.resolve ||= {}
    config.resolve.conditions ||= configDefaults.resolve.conditions
    config.resolve.conditions = config.resolve.conditions.filter(
      (c) => c !== 'node',
    )
  }
}

If we put the default conditions before config hooks (c8ab916), it will be easier to remove the defaults. But more CI failed 😅 (#18395 (comment)).

I'll revert to the original one (713cee3).

@vite-ecosystem-ci

This comment was marked as outdated.

@sapphi-red
Copy link
Member Author

Pushed a commit that removes webCompatible. Let's see if that reduces the fails.

@sapphi-red
Copy link
Member Author

/ecosystem-ci run

@vite-ecosystem-ci
Copy link

📝 Ran ecosystem CI on edcf8f3: Open

suite result latest scheduled
astro failure failure
histoire failure success
redwoodjs failure failure
remix failure failure
sveltekit failure failure
vike failure failure
vite-environment-examples failure success
vite-plugin-svelte failure failure
vitest failure failure

analogjs, ladle, laravel, marko, nuxt, previewjs, quasar, qwik, rakkas, storybook, unocss, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress

@sapphi-red sapphi-red marked this pull request as ready for review October 29, 2024 06:17
@sapphi-red sapphi-red added this to the 6.0 milestone Oct 29, 2024
Comment on lines 139 to 141
Some of the default conditions (`production`, `development`) are only applied when the requirements are met. For example, `production` is only applied when `process.env.NODE_ENV === 'production'`. The `resolve.conditions` config option allows specifying additional allowed conditions and those conditions will be applied unconditionally.

Note that `import`, `require`, `default` conditions are always applied if the requirements are met.
Copy link
Member

Choose a reason for hiding this comment

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

What is a good use case for not passing production and development?

I'm wondering if we should treat these two specially, like you do with import, require, default. Given that they are the only ones that are conditionally applied, it feels cleaner for resolve.conditions to be "the conditions that are always applied". We could add a way to pass a function for each condition to specify
the conditions for example if we want to explicitly define them, or ask for
['module', 'browser', 'node', process.env.NODE_ENV], maybe this should be the default if we keep it in the conditions?)

Copy link
Member Author

Choose a reason for hiding this comment

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

As we discussed in the team meeting, I introduced DEV_PROD_CONDITION variable that will be replaced with production or development: 4985011

Comment on lines 171 to +172
// @ts-expect-error - The log function is bound to inspectOpts, but the type is not reflected
if (depth && log.inspectOpts.depth == null) {
if (depth && log.inspectOpts && log.inspectOpts.depth == null) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know why but without this change, the test fails.

@sapphi-red
Copy link
Member Author

I have updated to be the behavior decided in the meeting.

Comment on lines 49 to 66
// using " and $ as conditions would usually avoid using $ or "
// as it makes difficult to use the condition in command line or json
// also avoiding a symbol so that dual package hazard won't be a problem
type SpecialCondition<T extends string> = `vite$"${T}"` & { __brand: never }

/**
* A special condition that would be replaced with production or development
* depending on NODE_ENV env variable
*/
export const DEV_PROD_CONDITION =
`vite$"dev-prod"` as SpecialCondition<'dev-prod'>

export const DEFAULT_CONDITIONS = [
'module',
'browser',
'node',
DEV_PROD_CONDITION,
]
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer we just use a string to be honest. I think the SpecialCondition is the right approach but it forces users to import it to use the option (that is the most common thing to do). If we want to add a special condition, maybe we could just add resolve.conditionDevProd: boolean defaulting to true.
If not, I think we could use a string like vite-dev-prod and there shouldn't be any chance or collision. But thinking a bit more in the API, I'm now leaning towards a new resolve.conditionDevProd option because vite-dev-prod will always be a footgun with a lot of users forgetting to add it. It makes the resolve.conditions option a lot trickier to use for the common case.

Copy link
Member

Choose a reason for hiding this comment

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

In the meeting I suggested that maybe we should keep using "production" and "development" still and avoid a magic string. If one of them is added, the other must exist or it'll warn (we'll auto add it anyways). That way both conditions will always exist. Perhaps this is a simpler approach so we don't have to introduce a new option?

Copy link
Member

Choose a reason for hiding this comment

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

Don't you think that a lot of people will forget to add , "production", "development"? If 99% of the time we need them there, I think resolve.conditionDevProd: boolean would lead to a better experience

Copy link
Member

Choose a reason for hiding this comment

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

I don't know if it'll be a common thing for people to do. IIUC we have the condition by default, so those who change the conditions are probably plugin/env authors so they'll be able to address this early on. And if we emit a warning, it should nudge the authors to the right direction without too much hassle I feel like 🤔

Copy link
Member

Choose a reason for hiding this comment

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

You can't emit a warning if people don't add production+development as that would be fine. Oh, you are saying that we can emit a warning if only one is added. What I'm worried about is that a lot of times these won't end up added. I prefer your idea to the custom symbol though, but I would still prefer the boolean. Curious to see what others think.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm fine with changing the string value to something that isn't that strange to write it directly in the config as long as it indicates it's a special value (It still works now when you write vite$"dev-prod" in the config directly instead of importing the variable). To raise a few ideas: @vite-dev-prod / _vite-dev-prod / vite:dev-prod / @vite:dev-prod.

vite-dev-prod will always be a footgun with a lot of users forgetting to add it.

I think this is not special to vite-dev-prod. All module, node, browser might be forgot to add by users. I think configDefaults would help in this case (at least not to forget updating the code when the default changes in future).

Copy link
Member

Choose a reason for hiding this comment

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

What about just vite_env, in reference to NODE_ENV?

Copy link
Member Author

Choose a reason for hiding this comment

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

For me, vite_env feels like it will be replaced with NODE_ENV which is not the case here.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, vite:dev-prod sounds ok. Other options development|production, dev|prod

Copy link
Member

@bluwy bluwy left a comment

Choose a reason for hiding this comment

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

LGTM. Makes sense to me to follow-up with a way to expose configDefaults or something too.

Copy link
Member

@patak-dev patak-dev left a comment

Choose a reason for hiding this comment

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

This will be huge for a cleaner future, thanks for pushing it through @sapphi-red

@@ -761,7 +761,7 @@ async function prepareEsbuildOptimizerRun(
),
}

const platform = environment.config.webCompatible ? 'browser' : 'node'
const platform = environment.config.consumer === 'client' ? 'browser' : 'node'
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this change is not correct, since there might be webCompatible servers such as Cloudflare's workerd

Copy link
Member Author

Choose a reason for hiding this comment

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

linking for future reference: #18611

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change feat: environment API Vite Environment API p3-significant High priority enhancement (priority)
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants