Skip to content

Commit

Permalink
refactor!: migrate to ESM (#7623)
Browse files Browse the repository at this point in the history
- Set `"type": "module"` to use ESM
- Migrate TypeScript config:
  - Decouple client/pwa/ssr config from base config, as it runs through Webpack, keep moduleResolution as Node
  - Set module/moduleResolution for everything else to NodeNext (necessary for import assertions)
  - Remove redundant `tsconfig.json` files (no need to include a file that simply extends the main file and nothing else; IDEs don't like them either)
- Imports:
  - Append all imports with extensions as applicable
  - Point to a folder's `index.js` (required by ESM)
  - Add import assertions as needed
  - Replace `require.resolve` with `resolve.sync`
  - Fix some imports/types where external packages are incompatible, see: tsconfig.paths
- Replace uses of `__dirname`/`__filename` and related path modifications with file URLs where applicable
- Remove code that sets `NODE_ENV` programmatically; `NODE_ENV` is supposed to be read-only (plus setting it has unintended side effects that carry through the rest of the program)
- Fix module mocking by using `jest.unstable_mockModule` vs. `module.feature = jest.fn()` (you're supposed to use `jest.mock` as it is; the other way may have unintended side effects)
- Add extension aliases to Webpack config to ensure Webpack's resolver considers `.ts` to be an alias to `.js` (to handle imports)

Co-authored-by: Claas Augner <[email protected]>
Co-authored-by: Schalk Neethling <[email protected]>
Co-authored-by: allo <[email protected]>
Co-authored-by: Leo McArdle <[email protected]>
  • Loading branch information
5 people authored Feb 8, 2023
1 parent c5aa267 commit d3f7ec1
Show file tree
Hide file tree
Showing 181 changed files with 1,258 additions and 1,102 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.js → .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { readGitignoreFiles } = require("eslint-gitignore");
const path = require("node:path");
const { readGitignoreFiles } = require("eslint-gitignore");

const ignores = readGitignoreFiles({
cwd: path.join(".git", "info"),
Expand Down Expand Up @@ -40,6 +40,12 @@ module.exports = {
"warn",
{ ignoreRestSiblings: true },
],
"n/no-extraneous-import": [
"error",
{
allowModules: ["@jest/globals"],
},
],
"n/no-missing-import": "off",
"n/no-unpublished-import": "off",
"n/shebang": "off",
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v16
v16.19
4 changes: 2 additions & 2 deletions build/build-options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dotenv from "dotenv";
dotenv.config();

import { FLAW_LEVELS, VALID_FLAW_CHECKS } from "../libs/constants";
import { FLAW_LEVELS, VALID_FLAW_CHECKS } from "../libs/constants/index.js";
import {
DEFAULT_FLAW_LEVELS,
FILES,
Expand All @@ -11,7 +11,7 @@ import {
FIX_FLAWS_DRY_RUN,
FIX_FLAWS_TYPES,
FIX_FLAWS_VERBOSE,
} from "../libs/env";
} from "../libs/env/index.js";

const options = Object.freeze({
flawLevels: parseFlawLevels(DEFAULT_FLAW_LEVELS),
Expand Down
11 changes: 6 additions & 5 deletions build/check-images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

import path from "node:path";

import sizeOf from "image-size";
import imagesize from "image-size";

import { Document, Image } from "../content";
import { FLAW_LEVELS } from "../libs/constants";
import { findMatchesInText } from "./matches-in-text";
import { DEFAULT_LOCALE } from "../libs/constants";
import { Document, Image } from "../content/index.js";
import { FLAW_LEVELS, DEFAULT_LOCALE } from "../libs/constants/index.js";
import { findMatchesInText } from "./matches-in-text.js";

const { default: sizeOf } = imagesize;

/**
* Mutate the `$` instance for image reference and if appropriate,
Expand Down
38 changes: 24 additions & 14 deletions build/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@ import zlib from "node:zlib";

import chalk from "chalk";
import cliProgress from "cli-progress";
import { program } from "@caporal/core";
import { prompt } from "inquirer";

import { Document, slugToFolder, translationsOf } from "../content";
import { CONTENT_ROOT, CONTENT_TRANSLATED_ROOT } from "../libs/env";
import { VALID_LOCALES } from "../libs/constants";
import caporal from "@caporal/core";
import inquirer from "inquirer";

import { Document, slugToFolder, translationsOf } from "../content/index.js";
import {
CONTENT_ROOT,
CONTENT_TRANSLATED_ROOT,
BUILD_OUT_ROOT,
} from "../libs/env/index.js";
import { VALID_LOCALES } from "../libs/constants/index.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { renderHTML } from "../ssr/dist/main";
import options from "./build-options";
import { buildDocument, BuiltDocument, renderContributorsTxt } from ".";
import { DocMetadata, Flaws } from "../libs/types";
import SearchIndex from "./search-index";
import { BUILD_OUT_ROOT } from "../libs/env";
import { makeSitemapXML, makeSitemapIndexXML } from "./sitemaps";
import { humanFileSize } from "./utils";
import { renderHTML } from "../ssr/dist/main.js";
import options from "./build-options.js";
import {
buildDocument,
BuiltDocument,
renderContributorsTxt,
} from "./index.js";
import { DocMetadata, Flaws } from "../libs/types/document.js";
import SearchIndex from "./search-index.js";
import { makeSitemapXML, makeSitemapIndexXML } from "./sitemaps.js";
import { humanFileSize } from "./utils.js";

const { program } = caporal;
const { prompt } = inquirer;

export type DocumentBuild = SkippedDocumentBuild | InteractiveDocumentBuild;

Expand Down
2 changes: 1 addition & 1 deletion build/document-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Document } from "../content";
import { Document } from "../content/index.js";

const TRANSFORM_STRINGS = new Map(
Object.entries({
Expand Down
4 changes: 2 additions & 2 deletions build/extract-sections.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as cheerio from "cheerio";
import { ProseSection, Section } from "../libs/types";
import { extractSpecifications } from "./extract-specifications";
import { ProseSection, Section } from "../libs/types/document.js";
import { extractSpecifications } from "./extract-specifications.js";

type SectionsAndFlaws = [Section[], string[]];

Expand Down
2 changes: 1 addition & 1 deletion build/extract-sidebar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cheerio from "cheerio";
import { Doc } from "../libs/types/document";
import { Doc } from "../libs/types/document.js";

/** Extract and mutate the $ if it as a "Quick_links" section.
* But only if it exists.
Expand Down
10 changes: 5 additions & 5 deletions build/extract-specifications.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { packageBCD } from "./resolve-bcd";
import * as bcd from "@mdn/browser-compat-data/types";
import { Specification } from "../libs/types/document";
import specs from "web-specs";
import web from "../kumascript/src/api/web";
import { packageBCD } from "./resolve-bcd.js";
import bcd from "@mdn/browser-compat-data/types";
import { Specification } from "../libs/types/document.js";
import specs from "web-specs/index.json" assert { type: "json" };
import web from "../kumascript/src/api/web.js";

export function extractSpecifications(
query: string | undefined,
Expand Down
2 changes: 1 addition & 1 deletion build/extract-summary.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cheerio from "cheerio";
import { ProseSection, Section } from "../libs/types/document";
import { ProseSection, Section } from "../libs/types/document.js";

/**
* Given an array of sections, return a plain text
Expand Down
2 changes: 1 addition & 1 deletion build/flaws/bad-bcd-queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { packageBCD } from "../resolve-bcd";
import { packageBCD } from "../resolve-bcd.js";

// Bad BCD queries are when the `<div class="bc-data">` tags have an
// ID (or even lack the `id` attribute) that don't match anything in the
Expand Down
17 changes: 9 additions & 8 deletions build/flaws/broken-links.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import fs from "node:fs";
import path from "node:path";

import fromMarkdown from "mdast-util-from-markdown";
import visit from "unist-util-visit";

import { Document, Redirect, Image } from "../../content";
import { findMatchesInText } from "../matches-in-text";
import { Document, Redirect, Image } from "../../content/index.js";
import { findMatchesInText } from "../matches-in-text.js";
import {
DEFAULT_LOCALE,
FLAW_LEVELS,
VALID_LOCALES,
} from "../../libs/constants";
import { isValidLocale } from "../../libs/locale-utils";

const dirname = __dirname;
} from "../../libs/constants/index.js";
import { isValidLocale } from "../../libs/locale-utils/index.js";

function findMatchesInMarkdown(rawContent, href) {
const matches = [];
Expand All @@ -27,10 +24,14 @@ function findMatchesInMarkdown(rawContent, href) {
}

const _safeToHttpsDomains = new Map();

function getSafeToHttpDomains() {
if (!_safeToHttpsDomains.size) {
const fileParsed = JSON.parse(
fs.readFileSync(path.join(dirname, "safe-to-https-domains.json"), "utf-8")
fs.readFileSync(
new URL("safe-to-https-domains.json", import.meta.url),
"utf-8"
)
);
Object.entries(fileParsed).forEach(([key, value]) =>
_safeToHttpsDomains.set(key, value)
Expand Down
2 changes: 1 addition & 1 deletion build/flaws/heading-links.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { findMatchesInText } from "../matches-in-text";
import { findMatchesInText } from "../matches-in-text.js";

// You're not allowed to have `<a>` elements inside `<h2>` or `<h3>` elements
// because those will be rendered out as "links to themselves".
Expand Down
27 changes: 15 additions & 12 deletions build/flaws/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ import path from "node:path";
import chalk from "chalk";
import { RequestError } from "got";

import { Document } from "../../content";
import { FLAW_LEVELS, VALID_FLAW_CHECKS } from "../../libs/constants";
import { DEFAULT_LOCALE } from "../../libs/constants";
import { Document } from "../../content/index.js";
import {
FLAW_LEVELS,
VALID_FLAW_CHECKS,
DEFAULT_LOCALE,
} from "../../libs/constants/index.js";
import {
replaceMatchesInText,
replaceMatchingLinksInMarkdown,
} from "../matches-in-text";
import { forceExternalURL, downloadAndResizeImage } from "../utils";
import { getBadBCDQueriesFlaws } from "./bad-bcd-queries";
import { getBrokenLinksFlaws } from "./broken-links";
import { getHeadingLinksFlaws } from "./heading-links";
import { getPreTagFlaws } from "./pre-tags";
export { injectSectionFlaws } from "./sections";
import { getUnsafeHTMLFlaws } from "./unsafe-html";
import { injectTranslationDifferences } from "./translation-differences";
} from "../matches-in-text.js";
import { forceExternalURL, downloadAndResizeImage } from "../utils.js";
import { getBadBCDQueriesFlaws } from "./bad-bcd-queries.js";
import { getBrokenLinksFlaws } from "./broken-links.js";
import { getHeadingLinksFlaws } from "./heading-links.js";
import { getPreTagFlaws } from "./pre-tags.js";
export { injectSectionFlaws } from "./sections.js";
import { getUnsafeHTMLFlaws } from "./unsafe-html.js";
import { injectTranslationDifferences } from "./translation-differences.js";

export interface Flaw {
explanation: any;
Expand Down
4 changes: 2 additions & 2 deletions build/flaws/pre-tags.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Flaw } from ".";
import { Flaw } from "./index.js";

import { getFirstMatchInText } from "../matches-in-text";
import { getFirstMatchInText } from "../matches-in-text.js";
const escapeHTML = (s) =>
s
.replace(/&/g, "&amp;")
Expand Down
2 changes: 1 addition & 1 deletion build/flaws/sections.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FLAW_LEVELS } from "../../libs/constants";
import { FLAW_LEVELS } from "../../libs/constants/index.js";

export function injectSectionFlaws(doc, flaws, options) {
if (!flaws.length) {
Expand Down
6 changes: 3 additions & 3 deletions build/flaws/translation-differences.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Flaw } from ".";
import { Flaw } from "./index.js";

import { Document, Translation } from "../../content";
import { DEFAULT_LOCALE } from "../../libs/constants";
import { Document, Translation } from "../../content/index.js";
import { DEFAULT_LOCALE } from "../../libs/constants/index.js";

export function injectTranslationDifferences(doc, $, document): Flaw[] {
const flaws = [];
Expand Down
6 changes: 3 additions & 3 deletions build/flaws/unsafe-html.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Flaw } from ".";
import { Flaw } from "./index.js";

import {
INTERACTIVE_EXAMPLES_BASE_URL,
LIVE_SAMPLES_BASE_URL,
} from "../../libs/env";
import { findMatchesInText } from "../matches-in-text";
} from "../../libs/env/index.js";
import { findMatchesInText } from "../matches-in-text.js";

const safeIFrameSrcs = [
// EmbedGHLiveSample.ejs
Expand Down
4 changes: 2 additions & 2 deletions build/git-history.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import fs from "node:fs";
import path from "node:path";

import { execGit } from "../content";
import { CONTENT_ROOT } from "../libs/env";
import { execGit } from "../content/index.js";
import { CONTENT_ROOT } from "../libs/env/index.js";

function getFromGit(contentRoot = CONTENT_ROOT) {
// If `contentRoot` was a symlink, the `repoRoot` won't be. That'll make it
Expand Down
52 changes: 28 additions & 24 deletions build/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Doc } from "../libs/types";
import fs from "node:fs";
import path from "node:path";

Expand All @@ -7,29 +6,34 @@ import {
MacroInvocationError,
MacroLiveSampleError,
MacroRedirectedLinkError,
} from "../kumascript/src/errors";

import { Document, Image, execGit } from "../content";
import { CONTENT_ROOT, REPOSITORY_URLS } from "../libs/env";
import * as kumascript from "../kumascript";

import { FLAW_LEVELS } from "../libs/constants";
import { extractSections } from "./extract-sections";
import { extractSidebar } from "./extract-sidebar";
import { extractSummary } from "./extract-summary";
export { default as SearchIndex } from "./search-index";
import { addBreadcrumbData } from "./document-utils";
import { fixFixableFlaws, injectFlaws, injectSectionFlaws } from "./flaws";
import { checkImageReferences, checkImageWidths } from "./check-images";
import { getPageTitle } from "./page-title";
import { syntaxHighlight } from "./syntax-highlight";
import { formatNotecards } from "./format-notecards";
import buildOptions from "./build-options";
export { gather as gatherGitHistory } from "./git-history";
export { buildSPAs } from "./spas";
import LANGUAGES_RAW from "../libs/languages";
import { safeDecodeURIComponent } from "../kumascript/src/api/util";
import { wrapTables } from "./wrap-tables";
} from "../kumascript/src/errors.js";

import { Doc } from "../libs/types/document.js";
import { Document, Image, execGit } from "../content/index.js";
import { CONTENT_ROOT, REPOSITORY_URLS } from "../libs/env/index.js";
import * as kumascript from "../kumascript/index.js";

import { FLAW_LEVELS } from "../libs/constants/index.js";
import { extractSections } from "./extract-sections.js";
import { extractSidebar } from "./extract-sidebar.js";
import { extractSummary } from "./extract-summary.js";
export { default as SearchIndex } from "./search-index.js";
import { addBreadcrumbData } from "./document-utils.js";
import {
fixFixableFlaws,
injectFlaws,
injectSectionFlaws,
} from "./flaws/index.js";
import { checkImageReferences, checkImageWidths } from "./check-images.js";
import { getPageTitle } from "./page-title.js";
import { syntaxHighlight } from "./syntax-highlight.js";
import { formatNotecards } from "./format-notecards.js";
import buildOptions from "./build-options.js";
export { gather as gatherGitHistory } from "./git-history.js";
export { buildSPAs } from "./spas.js";
import LANGUAGES_RAW from "../libs/languages/index.js";
import { safeDecodeURIComponent } from "../kumascript/src/api/util.js";
import { wrapTables } from "./wrap-tables.js";

const LANGUAGES = new Map(
Object.entries(LANGUAGES_RAW).map(([locale, data]) => {
Expand Down
2 changes: 1 addition & 1 deletion build/page-title.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Document } from "../content";
import { Document } from "../content/index.js";

/**
* Return the appropriate document title to go into the HTML <title>
Expand Down
5 changes: 3 additions & 2 deletions build/resolve-bcd.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Note! This is copied verbatim from stumptown-content
import bcdUntyped from "@mdn/browser-compat-data/forLegacyNode";
import { CompatData } from "@mdn/browser-compat-data/types";

import bcd from "@mdn/browser-compat-data";
const bcd = bcdUntyped as CompatData;

export function packageBCD(query) {
const data = query.split(".").reduce((prev, curr) => {
Expand Down
2 changes: 1 addition & 1 deletion build/search-index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getPopularities } from "../content";
import { getPopularities } from "../content/index.js";

// getPopularities() is memoized so it's fast to call repeatedly
const getPopularity = (item) => getPopularities().get(item.url) || 0;
Expand Down
Loading

0 comments on commit d3f7ec1

Please sign in to comment.