Skip to content

Commit

Permalink
add packageInfo to html header
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-burel committed Jun 18, 2020
1 parent 93d1790 commit b715f2e
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 23 deletions.
1 change: 0 additions & 1 deletion cypress/integration/vns/i18n.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ describe("i18n", () => {
});
describe("document", () => {
beforeEach(() => {
(cy as any).state("document").write("");
cy.resetDefaultLanguage();
});
// @see https://glebbahmutov.com/blog/ssr-e2e/ for testing recipes
Expand Down
6 changes: 6 additions & 0 deletions cypress/integration/vns/packageInfo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
describe("package.json info", () => {
it("adds app version in the html header", () => {
cy.visitAsHtml("/");
cy.get("html").should("have.attr", "data-app-version");
});
});
64 changes: 44 additions & 20 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ We demo Next.js 9.4 new feature, `.env` file support. Open `.env.development` to

Run `yarn auto-changelog` to compute a new changelog. Works best in combination with `yarn version` (to create git version tags automatically) and `git merge --no-ff your-feature` (to get merge commits).

## Various

### Passing package.json info to the client app

In `next.config.js`, you'll find a demonstration of how to **safely** inject informations from your `package.json` into your Next application.

For example, we use it to inject current version into the `html` tag for better deployment tracking.

## Internationalization (i18n)

### i18n without custom server
Expand Down Expand Up @@ -174,50 +182,66 @@ Initial setup based on [official Next example](https://github.com/mui-org/materi

We try to reduce the foot print of Material UI for an easy remove. In next iterations, we'll try to make it fully pluggable, like in Vulcan Meteor, so you can easily swap your UI system.

## To be done

### Storybook

## TODO
Write Storybook stories for full pages
MUI in storybook (pass theme etc.)
i18n in Storybook
Storybook static build (currently broken)

### i18n

Custom error page (with i18n name space to remove warning)

Add custom error page with i18n name space to remove warning
Automated translation extraction: https://react.i18next.com/guides/extracting-translations

### Material UI

Material UI

 ### Others
Easy switch between MUI, Bootstrap, and probably Tailwind

### Error and logs

Error boundary
NPM package.json version in custom document
Switch between MUI and Tailwind
MUI and i18n in Storybook
Redirection demo for private pages => demo a page that is not available for example, and redirect to home with an HTTP request
Cleaner debug call (active only when DEBUG=1)
Setup debug client side programmatically based on DEBUG environemnt variable
Error tracking with Sentry?

### Cypress

Demo after and before hooks
Automatically enable debug in Cypress

### GraphQL

Graphql code generator

### Demo custom server?

NOTE: Using a custom server to serve Next pages is not recommended. We may choose not to support this feature.

ts-node, nodemon to have hot reload
Jest for the custom server
Fullstack cypress testing/coverage of the custom server

 ### Others

Redirection demo for private pages => demo a page that is not available for Example, and redirect to home with an HTTP request
Remove debug routes from bundle
Document contribution process
Cleaner debug call (active only when DEBUG=1)
Storybook static build
Pure JS support (no TS), in cypress, in code, in storybook, in jest...
PErformance testing?
Jest for the custom server
Unified code coverage with server
A way to debug which files are built in TypeScript
MDX support
Prettier config
Doc for the perfect VS Code setup
TypeScript/Eslint security rules
Included docs, not bundled at build time
Select pages bundled at build time?
TypeScript for dynamic component
Error tracking with Sentry
USe ES6 in webpack configs (see electron-react-boilerplate for a demo)
Demo TypeScript for dynamic component
USe ES6 in webpack configs, next.config (see electron-react-boilerplate for a demo)
Reproduction of various small issues
Mock of next packages from storybook, in jest
Efficient plug to Vulcan
Vulcan package standard
Custom SSR server? to be avoided if possible
Fullstack cypress testing/coverage of the custom server
Write Storybook stories for full pages?
Define Vulcan package standard
41 changes: 40 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
const flowRight = require("lodash/flowRight");
const { extendNextConfig } = require("./packages/@vulcan/next"); // TODO: load from @vulcan/next when it's on NPM
const debug = require("debug")("next");
const debug = require("debug")("vns:next");

// fooBar => FOO_BAR
const camelToTitle = (camelStr) => {
return camelStr
.replace(/[A-Z]/g, " $1") // fooBar => foo Bar
.split(" ")
.map((t) => t.toUpperCase())
.join("_");
};

// NOTE: NEVER import package.json elswhere in your app!
// We can import it here because next.config is not in the client side bundle
// We then pass only the relevant values in the config
const packageJSON = require("./package.json");

// Add package.json metadata to runtime configs and environment
const withPkgInfo = (nextConfig = {}) => {
// Public
// It's still unclear where such config should go
// @see https://github.com/vercel/next.js/discussions/14308
const publicPkgInfo = {
version: packageJSON.version,
};
nextConfig.publicRuntimeConfig.pkgInfo = publicPkgInfo;
// Also enhance environment with the same infos
Object.entries(publicPkgInfo).map(([key, value]) => {
const envKey = `NEXT_PUBLIC_PKGINFO_${camelToTitle(key)}`;
nextConfig.env[envKey] = `${value}`; // we convert to string
});

return nextConfig;
};

// @see https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
module.exports = (phase, { defaultConfig }) => {
let extendedConfig;
extendedConfig = extendNextConfig(defaultConfig);

extendedConfig.env = {};
extendedConfig.serverRuntimeConfig = {};
extendedConfig.publicRuntimeConfig = {};

Expand All @@ -19,6 +53,11 @@ module.exports = (phase, { defaultConfig }) => {
extendedConfig = withBundleAnalyzer(extendedConfig);
}

extendedConfig = flowRight([
withPkgInfo,
// add other wrappers here
])(extendedConfig);

debug("Extended next config FINAL " + JSON.stringify(extendedConfig));

return extendedConfig;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"i18next-browser-languagedetector": "^4.2.0",
"i18next-http-backend": "^1.0.15",
"isomorphic-unfetch": "3.0.0",
"lodash": "^4.17.15",
"next": "9.4.0",
"next-i18next": "5.0.0-beta.2",
"next-with-apollo": "5.0.1",
Expand Down
5 changes: 4 additions & 1 deletion src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export default class MyDocument extends Document<VNSDocumentProps> {
render() {
const { i18nDocumentProps } = this.props;
return (
<Html {...i18nDocumentProps}>
<Html
{...i18nDocumentProps}
data-app-version={process.env.NEXT_PUBLIC_PKGINFO_VERSION}
>
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
Expand Down

0 comments on commit b715f2e

Please sign in to comment.