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

Pro 6694 breakpoint preview vite ready #9

Merged
merged 15 commits into from
Nov 7, 2024

Conversation

ValJed
Copy link
Contributor

@ValJed ValJed commented Nov 4, 2024

PRO-6694

Summary

Setups new plugin for mobile preview in the vite base config.

What are the specific steps to test this change?

Should be tested with this plugin when released.

⚠️ It's the reason tests are red.
Branch target should be removed before to merge.

What kind of change does this PR introduce?

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Build-related changes
  • Other

Make sure the PR fulfills these requirements:

  • It includes a) the existing issue ID being resolved, b) a convincing reason for adding this feature, or c) a clear description of the bug it resolves
  • The changelog is updated
  • Related documentation has been updated
  • Related tests have been updated

Copy link

linear bot commented Nov 4, 2024

@ValJed ValJed force-pushed the pro-6694-breakpoint-preview-vite-ready branch from fd4e113 to f06bcb0 Compare November 5, 2024 16:04
const {
plugins = [],
...postCssConfig
} = importedConfig.default || importedConfig;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Supports cmj and esm.

Copy link
Contributor

Choose a reason for hiding this comment

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

We need the official postcss loader.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

const postCssConfigPath = path.resolve(process.cwd(), 'postcss.config.js');
const importedConfig = isPublic && fs.existsSync(postCssConfigPath)
? await import(postCssConfigPath)
: {};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only try to get postcss project config file if in public mode.
We might use one in apostrophe for other plugins like autoprefixer?

Copy link
Contributor

Choose a reason for hiding this comment

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

Autoprefixer for Apos might make sense. I don't think Vite does anything related, I can't recall they are doing it by default (probably inspecting the relevant docs/research a bit is a good idea). If we decide to do that, you can add it directly in the apos base config (vite-apos-config.js). It will be merged with anything that potentially comes later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added autoprefixer only for apos builds as dicsussed


if (!Array.isArray(plugins)) {
util.error('WARNING: postcss.config.js must export an array of plugins');
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We force the user to use plugins as arrays like described in the doc, otherwise making the require from here would not work.
Like this:

import autoprefixer from 'autoprefixer';
import tailwindcss from 'tailwindcss';

export default {
  plugins: [ autoprefixer(), tailwindcss() ]
};

Not like this:

export default {
  plugins: {
    autoprefixed: {},
    tailwindcss: {}
  }
};

Copy link
Contributor

Choose a reason for hiding this comment

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

Look at my recommendation (HUGE) comment. Yes, this is a great idea and I also think we should throw and not only warn. The reason for that is:

  • If a project transitions to our Vite build and already has a postcss config due to internal other use of potscss, the project developers should be aware that there is a conflcit and they are breaking the Apostrophe build pipeline.
  • They can make a decision how to proceed because they know stuff is broken on build time, which is GOOD.

I also think we need to ping Bob so that he can add important warning boxes in the docs about the whole possible postcss configuration conflicts and requirements - this one can be cited from the Vite docs, link in my previous comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both versions are working with the loader now.

package.json Outdated
@@ -35,6 +35,7 @@
"dependencies": {
"@vitejs/plugin-vue": "^5.1.4",
"fs-extra": "^7.0.1",
"postcss-viewport-to-container-toggle": "github:apostrophecms/postcss-viewport-to-container-toggle#pro-6694-mobile-preview-plugin",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: update when plugin released.

@ValJed ValJed requested a review from myovchev November 5, 2024 16:16
@ValJed ValJed marked this pull request as draft November 5, 2024 16:22
Copy link
Contributor

@myovchev myovchev left a comment

Choose a reason for hiding this comment

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

I have outlined a more detailed strategy for implementing postcss by the Vite standards, preserving the experience that devs are used to. I also think a core patch is also required (to pass pre-processed mobile preview related options, translated to a "build module language"). This is important as we might want to have webpack build module one day and the whole doesn't scale well - any core internal change will break build modules.

lib/internals.js Outdated
sourceRoot: self.buildRootSource,
input: self.getBuildInputs('apos')
});
const postcssConfig = await vitePostcssConfig({
Copy link
Contributor

Choose a reason for hiding this comment

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

A better implementation of this would be:

  • Move the entire postcss config processing in its own async getPostcssConfig(options) method.
  • Inside of this method, detect the apos.assset.options and just send simple instructions to the config. Is the plugin enabled? Pass the configuration options that the config may pass directly to the plugin. Or even better, use the build options (see below) - they are cached in self.buildOptions.
  • What I think is really bad here, is that Vite module now knows Apostrophe core internals. Something I wanted to avoid. Vite module only cares about building. It shouldn't know anything about "mobile preview" or any other feature and business logic. We should decouple. So I really recommend to patch the core, find getBuildOptions() core asset method, and add additional build options, something like:
{
  postcssTransformViewport: {
  enable: self.options.breakpointPreviewMode?.enable,
  debug: self.options.breakpointPreviewMode?.debug === true,
  attr: 'data-breakpoint-preview-mode',
  hook: self.options.breakpointPreviewMode?.transform
}

Pass those to await getPostcssConfig({ ...self.buildOptions.postcssTransformViewport })

  • Remove all the business logic from vite-postcss-config.js. The config should only check if the plugin is needed, if yes load it and pass blindly the arguments. It should not perform any merges as well, a plain object containing only the known postcss plugin.
  • Back to getPostcssConfig, it loads the base postcss config using the factory function as it does now (but with the simple options described above). It also should take care of detecting the project level postcss config file (if any). And this is a no small task! More about it below. In the end it should use the Vite merge helper to merge our base config and loaded postcss config:
const finalPostcssConfig = await vite.mergeConfig(baseConfig, {
  css: {
    postcss: userConfig
  }
});
  • Loading the project level postcss config might be its own method as well. Reference to vite docs: https://vite.dev/config/shared-options.html#css-postcss. It shows that Vite itself attempts loading the config using a plugin - https://github.com/postcss/postcss-load-config?tab=readme-ov-file. And it's a pretty complex logic! I think our best move here is to use internally this plugin (it exports a single async function) and pass the proper configuration to it. It's pretty simple code, so implement this shouldn't be a problem. Note - use self.apos.rootDir as a base config location, because process.cwd() will break multisite.
  • In the end, make sure that loading user (project level) postcss config in getPostcssConfig happens conditionally based on an option. Switch this option off in getAposViteConfig, and on in getPublicViteConfig.
  • In the end, I would also recommend make the postcss plugin ESM module. I'm not sure what are the reasons for you to go back to CJS, but using a dynamic import() inside of the config file is OK and already done for our own plugin. The config factories are all async by design.


if (!Array.isArray(plugins)) {
util.error('WARNING: postcss.config.js must export an array of plugins');
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Look at my recommendation (HUGE) comment. Yes, this is a great idea and I also think we should throw and not only warn. The reason for that is:

  • If a project transitions to our Vite build and already has a postcss config due to internal other use of potscss, the project developers should be aware that there is a conflcit and they are breaking the Apostrophe build pipeline.
  • They can make a decision how to proceed because they know stuff is broken on build time, which is GOOD.

I also think we need to ping Bob so that he can add important warning boxes in the docs about the whole possible postcss configuration conflicts and requirements - this one can be cited from the Vite docs, link in my previous comment.

const postCssConfigPath = path.resolve(process.cwd(), 'postcss.config.js');
const importedConfig = isPublic && fs.existsSync(postCssConfigPath)
? await import(postCssConfigPath)
: {};
Copy link
Contributor

Choose a reason for hiding this comment

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

Autoprefixer for Apos might make sense. I don't think Vite does anything related, I can't recall they are doing it by default (probably inspecting the relevant docs/research a bit is a good idea). If we decide to do that, you can add it directly in the apos base config (vite-apos-config.js). It will be merged with anything that potentially comes later.

const {
plugins = [],
...postCssConfig
} = importedConfig.default || importedConfig;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need the official postcss loader.

sourceRoot: self.buildRootSource,
input: self.getBuildInputs('apos')
});
const postcssConfig = await self.getPostcssConfig(self.buildOptions, 'apos');
const aposConfig = vite.mergeConfig(config, postcssConfig);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

looks a bit messy to chain the merge configs but it should work well.

}

return vitePostcssConfig({ plugins: postcssPlugins });
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the logic here, tried the respect the plugins order. options coming from core.

@ValJed ValJed requested a review from myovchev November 6, 2024 16:22
Copy link
Contributor

@myovchev myovchev left a comment

Choose a reason for hiding this comment

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

LGTM

@ValJed ValJed marked this pull request as ready for review November 7, 2024 11:21
@ValJed ValJed merged commit be412d9 into main Nov 7, 2024
4 checks passed
@ValJed ValJed deleted the pro-6694-breakpoint-preview-vite-ready branch November 7, 2024 13:25
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.

2 participants