diff --git a/.gitignore b/.gitignore index cbdc7c1002d9..7a30f590d9a6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ starter-kits-data.json .DS_Store yarn-error.log package-lock.json +src/content/**/*_all.md \ No newline at end of file diff --git a/concatenate-docs.js b/concatenate-docs.js new file mode 100644 index 000000000000..5d2a7c48ec0f --- /dev/null +++ b/concatenate-docs.js @@ -0,0 +1,78 @@ +// start message +console.info("\x1b[0m\x1b[36mConcatenating help files of each directory to create chapter-wide help files to be used for printing help ...\x1b[0m"); + +// ------ various includes ------ +const fs = require("fs"); +const path = require("path"); +const os = require("os"); +const front = require("front-matter"); + +// root path +const rootPath = path.join("src", "content"); + +/* getDirectoryRecursive() recursively walks through + all sub directories of the provided root path, + concatenates the MarkDown files' content in + each directory, sorted by their FrontMatter sort + attribute, and creates a compound MarkDown file + named by using the directory name, prefixed by an + underscore and suffixed by "_all.md" from the + concatenated content in the corresponding directory. +*/ +(function getDirectoryRecursive(basePath) +{ + // log current working directory + console.log("\x1b[0m\x1b[32m " + basePath + "\x1b[0m"); + + // create destination file name of compound file + const targetFilePath = path.join(basePath, `${basePath.substr(rootPath.length).replace(/[/\\]/, "_")}_all.md`); + + if (fs.existsSync(targetFilePath)) fs.unlinkSync(targetFilePath); // delete target file if it already exists + + fs.readdir(basePath, function (err, fileNames) // list current working directory + { + if (err) throw err; + + let fileContents = []; + + for (let file of fileNames) // for each directory entry ... + { + const fullPath = path.join(basePath, file); + + if (fs.statSync(fullPath).isDirectory()) getDirectoryRecursive(fullPath); // if the directory entry is a directory, recurse into that directory + else if (fullPath.endsWith(".md")) // if the directory entry is a MarkDown file, add it to the list of files to be processed + { + let fc = fileContents[fileContents.length] = front(fs.readFileSync(fullPath).toString()); + + if (!fc.attributes.sort) --fileContents.length; // only include files providing a FrontMatter "sort" attribute + } + } + + // sort MarkDown files by FrontMatter "sort" attribute (QuickSort) + for (let i = 0;i < fileContents.length - 1;++i) + for (let j = i + 1;j < fileContents.length;++j) + { + const left = fileContents[i].attributes, right = fileContents[j].attributes; + + if (left.sort > right.sort + || left.sort == right.sort && left.title > right.title) + [fileContents[i], fileContents[j]] = [fileContents[j], fileContents[i]]; + } + + // write compound target file + const targetFile = fs.createWriteStream(targetFilePath); + + targetFile.on("error", (error) => { throw error; }); + + for (let file of fileContents) + { + targetFile.write(os.EOL + os.EOL + "# " + file.attributes.title + os.EOL); // use FrontMatter "title" attribute as main heading of target file + targetFile.write(file.body); + } + + targetFile.end(); + }); +})(rootPath); + +// end message +process.on("exit", () => { console.info("\x1b[0m\x1b[36mSuccessfully created \"_all.md\" help files in each directory within \"" + rootPath + "\".\x1b[0m"); }); \ No newline at end of file diff --git a/package.json b/package.json index 96f6834bb6f5..0cc1e167f949 100644 --- a/package.json +++ b/package.json @@ -33,11 +33,12 @@ "init:generated": "mkdirp ./generated/loaders && mkdirp ./generated/plugins ", "lint": "run-s lint:*", "lint:js": "eslint . --ext .js,.jsx,.md", - "lint:markdown": "markdownlint --rules markdownlint-rule-emphasis-style --config ./.markdownlint.json *.md ./src/content/*.md ./src/content/**/*.md", + "lint:markdown": "markdownlint --rules markdownlint-rule-emphasis-style --config ./.markdownlint.json --ignore *.md ./src/content/**/*.md", "lint:social": "alex . -q", "lint:prose": "cp .proselintrc ~/ && proselint src/content", "test": "npm run lint", - "sitemap": "cd build && sitemap-static --prefix=https://webpack.js.org/ > sitemap.xml" + "sitemap": "cd build && sitemap-static --prefix=https://webpack.js.org/ > sitemap.xml", + "chapterize": "node ./concatenate-docs.js" }, "husky": { "hooks": { diff --git a/src/components/Footer/Footer.scss b/src/components/Footer/Footer.scss index 106d52ec0de3..4388e8be401c 100644 --- a/src/components/Footer/Footer.scss +++ b/src/components/Footer/Footer.scss @@ -4,6 +4,10 @@ .footer { width: 100%; flex: 0 0 auto; + + @media print { + display: none !important; + } } .footer__inner { diff --git a/src/components/Page/Page.jsx b/src/components/Page/Page.jsx index a21ce4d20156..e2b93794f766 100644 --- a/src/components/Page/Page.jsx +++ b/src/components/Page/Page.jsx @@ -81,7 +81,7 @@ const Page = ({ page, section }) => { )} { contributors.length > 0 && ( -
+

Contributors

diff --git a/src/components/Page/Page.scss b/src/components/Page/Page.scss index 85c664e2fdfe..91b1b94bcafe 100644 --- a/src/components/Page/Page.scss +++ b/src/components/Page/Page.scss @@ -29,3 +29,10 @@ padding: 1.5em; } } + +.contributors__section, .interactive +{ + @media print { + display: none !important; + } +} \ No newline at end of file diff --git a/src/components/PageLinks/PageLinks.scss b/src/components/PageLinks/PageLinks.scss index 7f45b7ff1526..60624bdd51fc 100644 --- a/src/components/PageLinks/PageLinks.scss +++ b/src/components/PageLinks/PageLinks.scss @@ -2,6 +2,10 @@ @import 'functions'; .page-links { + @media print { + display: none !important; + } + position: absolute; display: none; top: 1.5em; diff --git a/src/content/configuration/optimization.md b/src/content/configuration/optimization.md index eddd7ff1419e..cc8bff689feb 100644 --- a/src/content/configuration/optimization.md +++ b/src/content/configuration/optimization.md @@ -250,6 +250,36 @@ module.exports = { }; ``` +## `optimization.chunkIds` + +`bool: false` `string: natural, named, size, total-size` + +Tells webpack which algorithm to use when choosing chunk ids. Setting `optimization.chunkIds` to `false` tells webpack that none of built-in algorithms should be used, as custom one can be provided via plugin. There are couple of defaults for `optimization.chunkIds`: + +- if [`optimization.occurrenceOrder`](#optimization-occurrenceorder) is enabled `optimization.chunkIds` is set to `'total-size'` +- Disregarding previous if, if [`optimization.namedChunks`](#optimization-namedchunks) is enabled `optimization.chunkIds` is set to `'named'` +- if none of the above, `optimization.namedChunks` will be defaulted to `'natural'` + +The following string values are supported: + +Option | Description +----------------------- | ----------------------- +`'natural'` | Numeric ids in order of usage. +`'named'` | Readable ids for better debugging. +`'size'` | Numeric ids focused on minimal initial download size. +`'total-size'` | numeric ids focused on minimal total download size. + +__webpack.config.js__ + +```js +module.exports = { + //... + optimization: { + chunkIds: 'named' + } +}; +``` + ## `optimization.nodeEnv` `string` `bool: false` diff --git a/src/content/plugins/ignore-plugin.md b/src/content/plugins/ignore-plugin.md index b7e4ca280b26..f9c3295583d9 100644 --- a/src/content/plugins/ignore-plugin.md +++ b/src/content/plugins/ignore-plugin.md @@ -40,7 +40,7 @@ new webpack.IgnorePlugin({ ## Example of ignoring Moment Locales -As of [moment](https://momentjs.com/) 2.18, all locales are bundled together with the core library (see [this GitHub issue](https://github.com/moment/moment/issues/2373)). +As of [moment](https://momentjs.com/) 2.18, all locales are bundled together with the core library (see [this GitHub issue](https://github.com/moment/moment/issues/2373)). The `resourceRegExp` parameter passed to `IgnorePlugin` is not tested against the resolved file names or absolute module names being imported or required, but rather against the _string_ passed to `require` or `import` _within the source code where the import is taking place_. For example, if you're trying to exclude `node_modules/moment/locale/*.js`, this won't work: