diff --git a/.github/workflows/CD_release_npm.yml b/.github/workflows/CD_release_npm.yml index 316010d..50432df 100644 --- a/.github/workflows/CD_release_npm.yml +++ b/.github/workflows/CD_release_npm.yml @@ -31,10 +31,13 @@ jobs: - run: | yarn install - yarn build + yarn build-mjml-react - name: Run semantic release (release + bump version) - run: npx semantic-release + run: | + cd dist + npx semantic-release env: + HUSKY: 0 NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/CI_PR_merge_checks.yml b/.github/workflows/CI_PR_merge_checks.yml index 84d44cd..9b9e977 100644 --- a/.github/workflows/CI_PR_merge_checks.yml +++ b/.github/workflows/CI_PR_merge_checks.yml @@ -20,7 +20,7 @@ jobs: - name: Build run: | yarn install - yarn build + yarn build-dist - name: Format run: yarn prettier --check . - name: Lint diff --git a/CONTRIBUTOR.md b/CONTRIBUTOR.md index 6773bb7..eecacbb 100644 --- a/CONTRIBUTOR.md +++ b/CONTRIBUTOR.md @@ -64,12 +64,13 @@ Then, you can run several commands: For building and testing: -- `yarn build-cjs` builds the cjs `dist/src` folder +- `yarn build-cjs` builds the cjs `dist` folder - `yarn build-esm` builds the esm `dist/esm` folder -- `yarn build` builds both the cjs and esm folders +- `yarn build-dist` builds both the cjs and esm folders +- `yarn build-mjml-react` builds all folders and prepares the dist folder for publishing - `yarn test` runs the test suite on the development `src` folder -- `yarn test-dist` builds and runs the test suite on the `dist/src` folder -- `yarn test-dist-skip-build` runs the test suite on `dist/src` without building +- `yarn test-dist` builds and runs the test suite on the `dist` folder +- `yarn test-dist-skip-build` runs the test suite on `dist` without building As pull requests contributed externally from Faire require approval to have workflows run, please ensure to test locally before pushing. diff --git a/README.md b/README.md index 15fb7e3..7d46779 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,10 @@ import { MjmlButton, MjmlImage, } from "@faire/mjml-react"; -// we're working on improving this in #64 -import { render } from "@faire/mjml-react/dist/src/utils/render"; +// The below render import was previously: +// import { render } from "@faire/mjml-react/dist/src/utils/render"; +// Please migrate to importing from "@faire/mjml-react/utils/render" +import { render } from "@faire/mjml-react/utils/render"; const { html, errors } = render( diff --git a/extensions.js b/extensions.js deleted file mode 100644 index d431323..0000000 --- a/extensions.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("./dist/src/extensions"); diff --git a/jest-dist.config.js b/jest-dist.config.js index 0ba10f0..866d390 100644 --- a/jest-dist.config.js +++ b/jest-dist.config.js @@ -5,6 +5,6 @@ const baseConfig = require("./jest.config"); module.exports = { ...baseConfig, moduleNameMapper: { - "src(.*)$": "/dist/src$1", + "src(.*)$": "/dist$1", }, }; diff --git a/package.json b/package.json index 7938e91..eeaf524 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,8 @@ "bugs": { "url": "https://github.com/Faire/mjml-react/issues" }, - "main": "dist/src/index.js", - "files": [ - "extensions.js", - "utils.js", - "dist" - ], - "types": "dist/src/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", "directories": { "test": "test" }, @@ -32,15 +27,16 @@ "access": "public" }, "scripts": { - "build": "/bin/rm -rf dist && yarn build-cjs && yarn build-esm", + "build-dist": "/bin/rm -rf dist && yarn build-cjs && yarn build-esm", "build-cjs": "tsc -p tsconfig.json", "build-esm": "tsc -p tsconfig-esm.json", "lint": "eslint .", "format": "prettier --write .", "test": "jest", "test-dist-skip-build": "jest --config=jest-dist.config.js", - "test-dist": "yarn build && yarn test-dist-skip-build", + "test-dist": "yarn build-dist && yarn test-dist-skip-build", "generate-mjml-react": "ts-node scripts/generate-mjml-react.ts", + "build-mjml-react": "ts-node scripts/build-mjml-react.ts", "prepare": "husky install" }, "devDependencies": { diff --git a/scripts/build-mjml-react.ts b/scripts/build-mjml-react.ts new file mode 100644 index 0000000..9083e69 --- /dev/null +++ b/scripts/build-mjml-react.ts @@ -0,0 +1,25 @@ +import { exec as execCb } from "child_process"; +import * as fs from "fs"; +import util from "util"; + +const exec = util.promisify(execCb); + +async function buildMjmlReact() { + await exec("yarn build-dist"); + moveFilesToDist(); +} + +const FILES_TO_COPY = ["package.json", "LICENSE", "README.md"]; +function moveFilesToDist() { + FILES_TO_COPY.forEach((fileToCopy) => { + const destination = `dist/${fileToCopy}`; + if (fileToCopy === "package.json") { + const file = fs.readFileSync(fileToCopy); + fs.writeFileSync(destination, file.toString().replace(/dist\//g, "")); + } else { + fs.copyFileSync(fileToCopy, destination); + } + }); +} + +buildMjmlReact(); diff --git a/scripts/generate-mjml-react.ts b/scripts/generate-mjml-react.ts index 5355232..d2669d0 100755 --- a/scripts/generate-mjml-react.ts +++ b/scripts/generate-mjml-react.ts @@ -15,6 +15,9 @@ import { typeToUnit } from "../src/utils"; const MJML_REACT_DIR = "src"; +const UTILS_FILE = "utils"; +const MJML_COMPONENTS_FOLDER = "mjml"; + const GENERATED_HEADER_TSX = ` /* * This file is generated. Don't edit it directly. @@ -235,7 +238,7 @@ ${GENERATED_HEADER_TSX} import React from "react"; -import { convertPropsToMjmlAttributes${unitsImports} } from "../utils"; +import { convertPropsToMjmlAttributes${unitsImports} } from "../${UTILS_FILE}"; export interface I${reactName}Props { ${types} @@ -267,7 +270,7 @@ function buildReactCreateElementProps(componentName: string): { } // reset directory -const GENERATED_MJML_FILES = path.join(MJML_REACT_DIR, "mjml"); +const GENERATED_MJML_FILES = path.join(MJML_REACT_DIR, MJML_COMPONENTS_FOLDER); del.sync(GENERATED_MJML_FILES); fs.mkdirSync(GENERATED_MJML_FILES); @@ -287,21 +290,33 @@ for (const mjmlComponent of MJML_COMPONENTS_TO_GENERATE) { } // create index export file for mjml-react components -const INDEX_FILE = path.join(MJML_REACT_DIR, `index.tsx`); +const MJML_INDEX_FILE = path.join(GENERATED_MJML_FILES, `index.tsx`); fs.writeFileSync( - INDEX_FILE, + MJML_INDEX_FILE, ` ${GENERATED_HEADER_TSX} ${MJML_COMPONENTS_TO_GENERATE.map(({ componentName }) => { const mjmlPackageName = componentName.replace("mj-", "mjml-"); const reactName = upperFirst(camelCase(mjmlPackageName)); - return `export { ${reactName} } from './mjml/${reactName}'; -export type { I${reactName}Props } from './mjml/${reactName}';`; + return `export { ${reactName} } from './${reactName}'; +export type { I${reactName}Props } from './${reactName}';`; }).join("\n")} ` ); +// create index export for main mjml-react package export +const MAIN_INDEX_FILE = path.join(MJML_REACT_DIR, `index.tsx`); +fs.writeFileSync( + MAIN_INDEX_FILE, + ` +${GENERATED_HEADER_TSX} + +export * from "./${UTILS_FILE}"; +export * from "./${MJML_COMPONENTS_FOLDER}"; +` +); + // generate gitattributes file const gitAttributes = MJML_COMPONENTS_TO_GENERATE.map(({ componentName }) => { const mjmlPackageName = componentName.replace("mj-", "mjml-"); @@ -319,5 +334,5 @@ ${gitAttributes} ); require("child_process").execSync( - `yarn prettier --write ${GENERATED_MJML_FILES} ${INDEX_FILE}` + `yarn prettier --write ${GENERATED_MJML_FILES} ${MJML_INDEX_FILE} ${MAIN_INDEX_FILE}` ); diff --git a/src/index.tsx b/src/index.tsx index 805c7bd..136ffdb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,77 +3,5 @@ * Modify `scripts/generate-mjml-react.ts` to make changes to these files */ -export { Mjml } from "./mjml/Mjml"; -export type { IMjmlProps } from "./mjml/Mjml"; -export { MjmlAll } from "./mjml/MjmlAll"; -export type { IMjmlAllProps } from "./mjml/MjmlAll"; -export { MjmlClass } from "./mjml/MjmlClass"; -export type { IMjmlClassProps } from "./mjml/MjmlClass"; -export { MjmlInclude } from "./mjml/MjmlInclude"; -export type { IMjmlIncludeProps } from "./mjml/MjmlInclude"; -export { MjmlHtmlAttribute } from "./mjml/MjmlHtmlAttribute"; -export type { IMjmlHtmlAttributeProps } from "./mjml/MjmlHtmlAttribute"; -export { MjmlSelector } from "./mjml/MjmlSelector"; -export type { IMjmlSelectorProps } from "./mjml/MjmlSelector"; -export { MjmlBody } from "./mjml/MjmlBody"; -export type { IMjmlBodyProps } from "./mjml/MjmlBody"; -export { MjmlHead } from "./mjml/MjmlHead"; -export type { IMjmlHeadProps } from "./mjml/MjmlHead"; -export { MjmlAttributes } from "./mjml/MjmlAttributes"; -export type { IMjmlAttributesProps } from "./mjml/MjmlAttributes"; -export { MjmlBreakpoint } from "./mjml/MjmlBreakpoint"; -export type { IMjmlBreakpointProps } from "./mjml/MjmlBreakpoint"; -export { MjmlHtmlAttributes } from "./mjml/MjmlHtmlAttributes"; -export type { IMjmlHtmlAttributesProps } from "./mjml/MjmlHtmlAttributes"; -export { MjmlFont } from "./mjml/MjmlFont"; -export type { IMjmlFontProps } from "./mjml/MjmlFont"; -export { MjmlPreview } from "./mjml/MjmlPreview"; -export type { IMjmlPreviewProps } from "./mjml/MjmlPreview"; -export { MjmlStyle } from "./mjml/MjmlStyle"; -export type { IMjmlStyleProps } from "./mjml/MjmlStyle"; -export { MjmlTitle } from "./mjml/MjmlTitle"; -export type { IMjmlTitleProps } from "./mjml/MjmlTitle"; -export { MjmlHero } from "./mjml/MjmlHero"; -export type { IMjmlHeroProps } from "./mjml/MjmlHero"; -export { MjmlButton } from "./mjml/MjmlButton"; -export type { IMjmlButtonProps } from "./mjml/MjmlButton"; -export { MjmlColumn } from "./mjml/MjmlColumn"; -export type { IMjmlColumnProps } from "./mjml/MjmlColumn"; -export { MjmlDivider } from "./mjml/MjmlDivider"; -export type { IMjmlDividerProps } from "./mjml/MjmlDivider"; -export { MjmlGroup } from "./mjml/MjmlGroup"; -export type { IMjmlGroupProps } from "./mjml/MjmlGroup"; -export { MjmlImage } from "./mjml/MjmlImage"; -export type { IMjmlImageProps } from "./mjml/MjmlImage"; -export { MjmlRaw } from "./mjml/MjmlRaw"; -export type { IMjmlRawProps } from "./mjml/MjmlRaw"; -export { MjmlSection } from "./mjml/MjmlSection"; -export type { IMjmlSectionProps } from "./mjml/MjmlSection"; -export { MjmlSpacer } from "./mjml/MjmlSpacer"; -export type { IMjmlSpacerProps } from "./mjml/MjmlSpacer"; -export { MjmlText } from "./mjml/MjmlText"; -export type { IMjmlTextProps } from "./mjml/MjmlText"; -export { MjmlTable } from "./mjml/MjmlTable"; -export type { IMjmlTableProps } from "./mjml/MjmlTable"; -export { MjmlWrapper } from "./mjml/MjmlWrapper"; -export type { IMjmlWrapperProps } from "./mjml/MjmlWrapper"; -export { MjmlSocial } from "./mjml/MjmlSocial"; -export type { IMjmlSocialProps } from "./mjml/MjmlSocial"; -export { MjmlSocialElement } from "./mjml/MjmlSocialElement"; -export type { IMjmlSocialElementProps } from "./mjml/MjmlSocialElement"; -export { MjmlNavbar } from "./mjml/MjmlNavbar"; -export type { IMjmlNavbarProps } from "./mjml/MjmlNavbar"; -export { MjmlNavbarLink } from "./mjml/MjmlNavbarLink"; -export type { IMjmlNavbarLinkProps } from "./mjml/MjmlNavbarLink"; -export { MjmlAccordion } from "./mjml/MjmlAccordion"; -export type { IMjmlAccordionProps } from "./mjml/MjmlAccordion"; -export { MjmlAccordionElement } from "./mjml/MjmlAccordionElement"; -export type { IMjmlAccordionElementProps } from "./mjml/MjmlAccordionElement"; -export { MjmlAccordionText } from "./mjml/MjmlAccordionText"; -export type { IMjmlAccordionTextProps } from "./mjml/MjmlAccordionText"; -export { MjmlAccordionTitle } from "./mjml/MjmlAccordionTitle"; -export type { IMjmlAccordionTitleProps } from "./mjml/MjmlAccordionTitle"; -export { MjmlCarousel } from "./mjml/MjmlCarousel"; -export type { IMjmlCarouselProps } from "./mjml/MjmlCarousel"; -export { MjmlCarouselImage } from "./mjml/MjmlCarouselImage"; -export type { IMjmlCarouselImageProps } from "./mjml/MjmlCarouselImage"; +export * from "./utils"; +export * from "./mjml"; diff --git a/src/mjml/index.tsx b/src/mjml/index.tsx new file mode 100644 index 0000000..4a85b1b --- /dev/null +++ b/src/mjml/index.tsx @@ -0,0 +1,79 @@ +/* + * This file is generated. Don't edit it directly. + * Modify `scripts/generate-mjml-react.ts` to make changes to these files + */ + +export { Mjml } from "./Mjml"; +export type { IMjmlProps } from "./Mjml"; +export { MjmlAll } from "./MjmlAll"; +export type { IMjmlAllProps } from "./MjmlAll"; +export { MjmlClass } from "./MjmlClass"; +export type { IMjmlClassProps } from "./MjmlClass"; +export { MjmlInclude } from "./MjmlInclude"; +export type { IMjmlIncludeProps } from "./MjmlInclude"; +export { MjmlHtmlAttribute } from "./MjmlHtmlAttribute"; +export type { IMjmlHtmlAttributeProps } from "./MjmlHtmlAttribute"; +export { MjmlSelector } from "./MjmlSelector"; +export type { IMjmlSelectorProps } from "./MjmlSelector"; +export { MjmlBody } from "./MjmlBody"; +export type { IMjmlBodyProps } from "./MjmlBody"; +export { MjmlHead } from "./MjmlHead"; +export type { IMjmlHeadProps } from "./MjmlHead"; +export { MjmlAttributes } from "./MjmlAttributes"; +export type { IMjmlAttributesProps } from "./MjmlAttributes"; +export { MjmlBreakpoint } from "./MjmlBreakpoint"; +export type { IMjmlBreakpointProps } from "./MjmlBreakpoint"; +export { MjmlHtmlAttributes } from "./MjmlHtmlAttributes"; +export type { IMjmlHtmlAttributesProps } from "./MjmlHtmlAttributes"; +export { MjmlFont } from "./MjmlFont"; +export type { IMjmlFontProps } from "./MjmlFont"; +export { MjmlPreview } from "./MjmlPreview"; +export type { IMjmlPreviewProps } from "./MjmlPreview"; +export { MjmlStyle } from "./MjmlStyle"; +export type { IMjmlStyleProps } from "./MjmlStyle"; +export { MjmlTitle } from "./MjmlTitle"; +export type { IMjmlTitleProps } from "./MjmlTitle"; +export { MjmlHero } from "./MjmlHero"; +export type { IMjmlHeroProps } from "./MjmlHero"; +export { MjmlButton } from "./MjmlButton"; +export type { IMjmlButtonProps } from "./MjmlButton"; +export { MjmlColumn } from "./MjmlColumn"; +export type { IMjmlColumnProps } from "./MjmlColumn"; +export { MjmlDivider } from "./MjmlDivider"; +export type { IMjmlDividerProps } from "./MjmlDivider"; +export { MjmlGroup } from "./MjmlGroup"; +export type { IMjmlGroupProps } from "./MjmlGroup"; +export { MjmlImage } from "./MjmlImage"; +export type { IMjmlImageProps } from "./MjmlImage"; +export { MjmlRaw } from "./MjmlRaw"; +export type { IMjmlRawProps } from "./MjmlRaw"; +export { MjmlSection } from "./MjmlSection"; +export type { IMjmlSectionProps } from "./MjmlSection"; +export { MjmlSpacer } from "./MjmlSpacer"; +export type { IMjmlSpacerProps } from "./MjmlSpacer"; +export { MjmlText } from "./MjmlText"; +export type { IMjmlTextProps } from "./MjmlText"; +export { MjmlTable } from "./MjmlTable"; +export type { IMjmlTableProps } from "./MjmlTable"; +export { MjmlWrapper } from "./MjmlWrapper"; +export type { IMjmlWrapperProps } from "./MjmlWrapper"; +export { MjmlSocial } from "./MjmlSocial"; +export type { IMjmlSocialProps } from "./MjmlSocial"; +export { MjmlSocialElement } from "./MjmlSocialElement"; +export type { IMjmlSocialElementProps } from "./MjmlSocialElement"; +export { MjmlNavbar } from "./MjmlNavbar"; +export type { IMjmlNavbarProps } from "./MjmlNavbar"; +export { MjmlNavbarLink } from "./MjmlNavbarLink"; +export type { IMjmlNavbarLinkProps } from "./MjmlNavbarLink"; +export { MjmlAccordion } from "./MjmlAccordion"; +export type { IMjmlAccordionProps } from "./MjmlAccordion"; +export { MjmlAccordionElement } from "./MjmlAccordionElement"; +export type { IMjmlAccordionElementProps } from "./MjmlAccordionElement"; +export { MjmlAccordionText } from "./MjmlAccordionText"; +export type { IMjmlAccordionTextProps } from "./MjmlAccordionText"; +export { MjmlAccordionTitle } from "./MjmlAccordionTitle"; +export type { IMjmlAccordionTitleProps } from "./MjmlAccordionTitle"; +export { MjmlCarousel } from "./MjmlCarousel"; +export type { IMjmlCarouselProps } from "./MjmlCarousel"; +export { MjmlCarouselImage } from "./MjmlCarouselImage"; +export type { IMjmlCarouselImageProps } from "./MjmlCarouselImage"; diff --git a/src/utils/index.ts b/src/utils/index.ts index fd9a4d9..3d341ed 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ export { namedEntityToHexCode } from "./html-entities"; +export * from "./mjml-component-utils"; diff --git a/src/utils.tsx b/src/utils/mjml-component-utils.ts similarity index 100% rename from src/utils.tsx rename to src/utils/mjml-component-utils.ts diff --git a/test/__mockData__/mockMjmlReactTestData.tsx b/test/__mockData__/mockMjmlReactTestData.tsx index 33f0163..3f0004a 100644 --- a/test/__mockData__/mockMjmlReactTestData.tsx +++ b/test/__mockData__/mockMjmlReactTestData.tsx @@ -1,6 +1,6 @@ import React from "react"; -import * as mjmlComponents from "../../src"; +import * as mjmlComponents from "../../src/mjml"; const { Mjml, @@ -43,6 +43,7 @@ const { } = mjmlComponents; type AllComponents = keyof typeof mjmlComponents; + type MjmlComponentTest = { mjmlReact: React.ReactElement; expectedMjml: string; diff --git a/tsconfig-eslint.json b/tsconfig-eslint.json index 6730764..b6c0433 100644 --- a/tsconfig-eslint.json +++ b/tsconfig-eslint.json @@ -3,7 +3,7 @@ "compilerOptions": { "module": "CommonJS", "target": "es2015", - "outDir": "dist/src", + "outDir": "dist", "declaration": true }, "include": ["**/*", ".eslintrc.js"] diff --git a/tsconfig.json b/tsconfig.json index a935747..1d7ad05 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "module": "CommonJS", "target": "es2015", - "outDir": "dist/src", + "outDir": "dist", "declaration": true } } diff --git a/utils.js b/utils.js deleted file mode 100644 index b047333..0000000 --- a/utils.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("./dist/src/utils/index");