Skip to content

Commit

Permalink
feat(cli): add opt-in experimental support for Vite bundler (#2568)
Browse files Browse the repository at this point in the history
* refactor: use vite

* feat(mc-scripts): add experimental support for Vite bundler

* refactor: use experimental bundler in playground

* docs: changesets

* fix: use preval macro for preloading static file on build

* chore: rename env var

* fix(mc-scripts): dynamically change public path of assets on runtime for cdnUrl

* fix(mc-scripts): revert unnecessary change

* refactor: simplify logic

* refactor(mc-scripts): drop support for dynamic runtime base path (cdnUrl) and improve changeset
  • Loading branch information
emmenko committed Apr 28, 2022
1 parent 5b06e97 commit 5bcf106
Show file tree
Hide file tree
Showing 47 changed files with 597 additions and 173 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-spies-vanish.md
@@ -0,0 +1,5 @@
---
'@commercetools-frontend/mc-dev-authentication': patch
---

Expose new middleware `createMcDevAuthenticationMiddleware`. This is mostly used for internal development.
25 changes: 25 additions & 0 deletions .changeset/fair-poets-watch.md
@@ -0,0 +1,25 @@
---
'@commercetools-frontend/mc-dev-authentication': minor
'@commercetools-frontend/mc-html-template': minor
'@commercetools-frontend/mc-scripts': minor
---

Enable opt-in support for using [Vite.js](https://vitejs.dev/) bundler. To enable it, set the environment variable `ENABLE_EXPERIMENTAL_VITE_BUNDLER="true"` in your dotenv file.

# Why Vite

Vite (French word for "quick", pronounced /vit/, like "veet") is a build tool that aims to provide a faster and leaner development experience for modern web projects.

You can learn more about the rationale behind the project in the [Why Vite](https://vitejs.dev/guide/why.html) documentation.

# Native ES Modules support

Vite is optimized for using native [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) via `<script type="module">` tags and ES Modules dynamic import.

# CLI compatibility

All the `mc-scripts` CLI commands are fully compatible with the new bundler, so you can continue using them as before.

## Unsupported features

The `cdnUrl` value is not supported at the moment when using Vite.
6 changes: 6 additions & 0 deletions .changeset/forty-actors-retire.md
@@ -0,0 +1,6 @@
---
'merchant-center-application-template-starter': patch
'playground': patch
---

Rename files using JSX to `.jsx`
5 changes: 5 additions & 0 deletions .changeset/silver-owls-check.md
@@ -0,0 +1,5 @@
---
'playground': patch
---

Use new experimental bundler
5 changes: 5 additions & 0 deletions .changeset/sixty-hotels-kneel.md
@@ -0,0 +1,5 @@
---
'@commercetools-frontend/mc-html-template': patch
---

Extract html template into separate file for better reusability.
4 changes: 4 additions & 0 deletions @types-extensions/css/index.d.ts
Expand Up @@ -2,3 +2,7 @@ declare module '*.mod.css' {
const classes: { [key: string]: string };
export default classes;
}
declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;
}
@@ -1,4 +1,4 @@
import React from 'react';
import { lazy } from 'react';
import {
ApplicationShell,
setupGlobalErrorListener,
Expand All @@ -8,7 +8,7 @@ import loadMessages from '../../load-messages';
// Here we split up the main (app) bundle with the actual application business logic.
// Splitting by route is usually recommended and you can potentially have a splitting
// point for each route. More info at https://reactjs.org/docs/code-splitting.html
const AsyncApplicationRoutes = React.lazy(() =>
const AsyncApplicationRoutes = lazy(() =>
import('../../routes' /* webpackChunkName: "routes" */)
);

Expand Down
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,76 @@
const path = require('path');
const pug = require('pug');
const { logout } = require('../routes');

const compileLoginView = pug.compileFile(
path.join(__dirname, '../views/login.pug')
);
const compileLogoutView = pug.compileFile(
path.join(__dirname, '../views/logout.pug')
);

function createMcDevAuthenticationMiddleware(applicationConfig) {
const htmlLogin = compileLoginView({ env: applicationConfig.env });
const htmlLogout = compileLogoutView({ env: applicationConfig.env });

const isDevAuthenticationMiddlewareDisabled =
String(applicationConfig.env.disableAuthRoutesOfDevServer) === 'true' ||
applicationConfig.env.servedByProxy;

/**
* @type {import('express').RequestHandler}
*/
return (request, response, next) => {
if (request.originalUrl === '/api/graphql') {
response.statusCode = 404;
response.setHeader('Content-Type', 'application/json');
response.end(
JSON.stringify({
message: `This GraphQL endpoint is only available in production in the [Merchant Center Proxy Router](https://docs.commercetools.com/custom-applications/concepts/merchant-center-proxy-router). Please check that you are not calling this endpoint in development mode.`,
})
);
return;
}

if (applicationConfig.env.__DEVELOPMENT__?.oidc?.authorizeUrl) {
// Handle login page for OIDC workflow when developing against a local MC API.
if (
applicationConfig.env.__DEVELOPMENT__?.oidc?.authorizeUrl.startsWith(
'http://localhost'
)
) {
if (request.originalUrl.startsWith('/login/authorize')) {
if (isDevAuthenticationMiddlewareDisabled) {
next();
} else {
response.end(htmlLogin);
}
return;
}
}
} else {
if (request.originalUrl === '/login') {
if (isDevAuthenticationMiddlewareDisabled) {
next();
} else {
response.end(htmlLogin);
}
return;
}
if (request.originalUrl === '/logout') {
logout(response);

if (isDevAuthenticationMiddlewareDisabled) {
next();
} else {
response.end(htmlLogout);
}
return;
}
}

next();
};
}

module.exports = createMcDevAuthenticationMiddleware;
2 changes: 2 additions & 0 deletions packages/mc-dev-authentication/middlewares/index.js
@@ -1,7 +1,9 @@
const createLoginMiddleware = require('./create-login-middleware');
const createLogoutMiddleware = require('./create-logout-middleware');
const createMcDevAuthenticationMiddleware = require('./create-mc-dev-authentication-middleware');

module.exports = {
createLoginMiddleware,
createLogoutMiddleware,
createMcDevAuthenticationMiddleware,
};
12 changes: 0 additions & 12 deletions packages/mc-dev-authentication/transformer-local.js
Expand Up @@ -24,18 +24,6 @@ module.exports = ({ env }) => {
const loginViewHtml = compileLoginView({ env });
const logoutViewHtml = compileLogoutView({ env });

fs.copyFileSync(
path.join(__dirname, 'views', 'login.css'),
path.join(paths.appBuild, 'login.css')
);
fs.copyFileSync(
path.join(__dirname, 'views', 'login.js'),
path.join(paths.appBuild, 'login.js')
);
fs.copyFileSync(
path.join(__dirname, 'views', 'logout.js'),
path.join(paths.appBuild, 'logout.js')
);
fs.writeFileSync(
path.join(paths.appBuild, 'login.html'),
loginViewHtml,
Expand Down
72 changes: 72 additions & 0 deletions packages/mc-html-template/html-docs/application.html
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="referrer" content="no-referrer">

<meta http-equiv="Content-Security-Policy" content="__CSP__">

<!-- Preconnects -->
<link rel="preconnect" href="__CDN_URL__">
<link rel="preconnect" href="__MC_API_URL__">

<!-- Fav and touch icons -->
<link rel="shortcut icon" type="image/png" href="__CDN_URL__favicon.png">
<!-- Standard iPhone -->
<link rel="apple-touch-icon" sizes="57x57" href="__CDN_URL__favicon_57x57px.png">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="__CDN_URL__favicon_57x57px.png">
<!-- Standard iPad -->
<link rel="apple-touch-icon" sizes="72x72" href="__CDN_URL__favicon_72x72px.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="__CDN_URL__favicon_72x72px.png">
<!-- Retina iPad -->
<link rel="apple-touch-icon" sizes="144x144" href="__CDN_URL__favicon_144x144px.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="__CDN_URL__favicon_144x144px.png">

<!-- Fonts -->
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i' rel='stylesheet' type='text/css'>

__APPLICATION_CSS_IMPORTS__

<title>Merchant Center</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

<div id="app-loader">
<!-- Loading screen styles -->
__LOADING_SCREEN_CSS__

<div class="loading-screen loading-screen--hidden">
<svg class="loading-spinner" viewBox="0 0 40 40">
<path class="loading-spinner-circle" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946, 14.946,14.946 s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"></path>
<path class="loading-spinner-pointer" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 C22.32,8.481,24.301,9.057,26.013,10.047z"></path>
</svg>
<svg width="200" height="29" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M38.342 20.486c1.102 0 1.738-.073 3.133-.367l.343 2.35c-1.077.293-2.276.44-3.476.44-5.358 0-6.9-3.353-6.9-7.268.049-3.818 2.35-7.048 6.876-7.048 1.2 0 2.227.147 3.475.465l-.465 2.325c-1.321-.294-2.104-.342-2.936-.342-2.839.048-4.234 2.153-4.283 4.6 0 2.422.906 4.845 4.233 4.845M49.304 20.51c2.814-.024 3.72-2.3 3.72-4.77-.024-2.253-.98-4.798-3.744-4.798-2.692.025-3.745 2.521-3.745 4.797 0 2.569 1.126 4.771 3.769 4.771zm0-11.917c4.405.025 6.363 3.304 6.363 7.146 0 3.744-1.689 7.096-6.387 7.12-4.601-.048-6.363-3.376-6.363-7.12 0-3.842 1.982-7.097 6.387-7.146zM73.896 22.615v-8.81c0-2.226-.832-2.838-2.227-2.838-.954 0-2.031.539-3.01 1.346.05.294.073.88.073 1.052v9.25h-2.74v-8.907c0-2.227-.661-2.766-2.056-2.766-.88 0-2.104.588-3.157 1.371v10.302h-2.716V8.838h2.716v1.174c.832-.66 2.154-1.419 3.597-1.443 1.91-.024 3.01.636 3.623 1.664 1.125-1.052 2.79-1.64 4.062-1.664 4.478-.074 4.55 3.523 4.55 5.04v9.006h-2.715M95.427 22.615v-8.81c0-2.226-.831-2.838-2.226-2.838-.955 0-2.032.539-3.01 1.346.049.294.073.88.073 1.052v9.25h-2.74v-8.907c0-2.227-.662-2.766-2.057-2.766-.88 0-2.104.588-3.157 1.371v10.302h-2.716V8.838h2.716v1.174c.833-.66 2.154-1.419 3.598-1.443 1.908-.024 3.01.636 3.622 1.664 1.126-1.052 2.79-1.64 4.062-1.664 4.478-.074 4.551 3.523 4.551 5.04v9.006h-2.716M103.035 14.124h6.044c-.098-2.79-1.492-3.353-2.789-3.353-2.056-.024-3.01 1.37-3.255 3.353zm7.782 5.97l.416 2.227c-1.224.416-2.912.612-4.233.612-5.433 0-6.755-3.646-6.755-7.292s1.616-7.023 6.167-7.023c2.814 0 5.163 1.737 5.188 6.166l-.025 1.444h-8.662c.049 2.692 1.493 4.331 4.209 4.331 1.076 0 2.202-.122 3.695-.465zM121.582 11.358a7.379 7.379 0 0 0-1.762-.195c-1.689-.025-2.57.808-3.206 1.468v9.984h-2.716V8.838h2.716v1.223a4.503 4.503 0 0 1 3.182-1.395 6.356 6.356 0 0 1 2.275.368l-.489 2.324M129.533 20.486c1.102 0 1.738-.073 3.132-.367l.344 2.35c-1.077.293-2.276.44-3.476.44-5.359 0-6.9-3.353-6.9-7.268.049-3.818 2.349-7.048 6.876-7.048 1.2 0 2.227.147 3.475.465l-.465 2.325c-1.322-.294-2.105-.342-2.936-.342-2.839.048-4.234 2.153-4.284 4.6 0 2.422.907 4.845 4.234 4.845M136.898 14.124h6.045c-.098-2.79-1.493-3.353-2.79-3.353-2.056-.024-3.01 1.37-3.255 3.353zm7.782 5.97l.416 2.227c-1.224.416-2.912.612-4.234.612-5.432 0-6.754-3.646-6.754-7.292s1.616-7.023 6.167-7.023c2.815 0 5.164 1.737 5.188 6.166l-.024 1.444h-8.663c.049 2.692 1.493 4.331 4.209 4.331 1.076 0 2.202-.122 3.695-.465zM154.662 11.09h-3.744v6.68c0 1.394.171 2.374 1.59 2.569.784.074 1.591 0 2.374-.098l.171 2.35c-.807.146-1.957.17-2.422.17-3.206-.121-4.405-1.761-4.405-4.33v-7.342h-1.982V9.205l1.982-.22V5.779h2.692v3.06h3.744v2.25M162.565 20.51c2.815-.024 3.72-2.3 3.72-4.77-.024-2.253-.979-4.798-3.744-4.798-2.692.025-3.745 2.521-3.745 4.797 0 2.569 1.127 4.771 3.77 4.771zm0-11.917c4.405.025 6.363 3.304 6.363 7.146 0 3.744-1.689 7.096-6.387 7.12-4.6-.048-6.363-3.376-6.363-7.12 0-3.842 1.982-7.097 6.387-7.146zM177.197 20.51c2.814-.024 3.72-2.3 3.72-4.77-.025-2.253-.98-4.798-3.744-4.798-2.692.025-3.745 2.521-3.745 4.797 0 2.569 1.126 4.771 3.769 4.771zm0-11.917c4.405.025 6.363 3.304 6.363 7.146 0 3.744-1.69 7.096-6.387 7.12-4.601-.048-6.363-3.376-6.363-7.12 0-3.842 1.982-7.097 6.387-7.146zM185.71 22.615h2.619V3.919h-2.619zM191.094 19.948c1.542.391 2.985.587 3.89.587 1.078 0 2.179-.22 2.252-1.517.074-1.37-1.346-1.787-2.96-2.472-1.836-.758-3.818-1.786-3.77-4.331.05-1.273.808-3.769 4.87-3.646 1.224.024 2.692.22 3.915.538l-.464 2.251c-1.444-.342-2.52-.49-3.573-.513-1.175 0-2.08.367-2.129 1.468-.024.93.71 1.42 2.52 2.153 1.836.759 4.43 1.738 4.308 4.625-.074 1.835-1.273 3.842-4.968 3.793-1.175-.024-3.059-.171-4.453-.66l.562-2.276" fill="#27373C"/>
<path d="M.349 22.312a.601.601 0 0 0-.002 1.091l11.663 5.46c.156.074.325.112.493.113V16.787c-.173 0-.346.037-.508.112L.35 22.312" fill="#E3712C"/>
<path d="M12.503 16.787v12.19c.18.003.361-.035.528-.113l11.63-5.444a.6.6 0 0 0-.002-1.09L13.011 16.9a1.2 1.2 0 0 0-.508-.113" fill="#EBA13B"/>
<path d="M0 6.363a.596.596 0 0 0 .347.546l11.663 5.46a1.194 1.194 0 0 0 .93.039l.327-.152c1.203-.56.406-.187 11.394-5.33a.6.6 0 0 0-.002-1.091L13.011.405a1.205 1.205 0 0 0-1.016 0L.35 5.818A.603.603 0 0 0 0 6.363" fill="#23A486"/>
<path d="M12.503 13.168v3.62c-.173 0-.346.036-.508.111L.35 22.312a.601.601 0 0 0-.348.545L0 6.77v-.407c0 .234.134.447.346.546l11.664 5.46a1.194 1.194 0 0 0 .93.039l-.02.009c-.362.167-.417.334-.417.75" fill="#CCCCC7"/>
</g>
</svg>
<p class="long-loading-notice long-loading-notice--hidden">Sorry, this is taking an unusually long time.</p>
</div>
</div>
<div id="app"></div>

<!-- Loading screen handling -->
__LOADING_SCREEN_JS__

<!-- Application globals -->
<script>window.app = __APPLICATION_ENVIRONMENT__;</script>

<!-- Tracking scripts (load before application bundles) -->
__DATALAYER_JS__
__GTM_SCRIPT__

<!-- Main application chunks -->
__APPLICATION_SCRIPT_IMPORTS__
</body>
</html>
11 changes: 11 additions & 0 deletions packages/mc-html-template/html-scripts/public-path.js
@@ -0,0 +1,11 @@
window.__dynamicImportHandler__ = function (importer) {
return `${window.app.cdnUrl.replace(/\/$/, '')}/${importer.replace(
/^(\.\/)?/,
''
)}`;
};
window.__dynamicImportPreload__ = function (preloads) {
return preloads.map(
(preload) => `${window.app.cdnUrl.replace(/\/$/, '')}/${preload}`
);
};
12 changes: 3 additions & 9 deletions packages/mc-html-template/package.json
Expand Up @@ -15,15 +15,7 @@
"access": "public"
},
"main": "./build/index.js",
"files": [
"build",
"html-scripts",
"html-styles",
"webpack.js",
"package.json",
"LICENSE",
"README.md"
],
"files": ["build", "webpack.js", "package.json", "LICENSE", "README.md"],
"scripts": {
"build": "rimraf build && babel src --out-dir build",
"build:bundles:watch": "yarn build -w"
Expand All @@ -41,6 +33,7 @@
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"babel-plugin-preval": "^5.1.0",
"rimraf": "3.0.2"
},
"engines": {
Expand All @@ -61,6 +54,7 @@
]
],
"plugins": [
"preval",
[
"@babel/plugin-transform-runtime",
{
Expand Down

1 comment on commit 5bcf106

@vercel
Copy link

@vercel vercel bot commented on 5bcf106 Apr 28, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.