refactor(plugin-pwa): migrate package to TS (#5941)

This commit is contained in:
Armano 2021-11-16 20:38:14 +01:00 committed by GitHub
parent 425144afc7
commit 85fcd9eb0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 147 additions and 32 deletions

View file

@ -13,6 +13,7 @@ packages/lqip-loader/lib/
packages/docusaurus/lib/ packages/docusaurus/lib/
packages/docusaurus-*/lib/* packages/docusaurus-*/lib/*
packages/docusaurus-*/lib-next/ packages/docusaurus-*/lib-next/
packages/docusaurus-plugin-pwa/copyUntypedFiles.js
packages/docusaurus-plugin-ideal-image/copyUntypedFiles.js packages/docusaurus-plugin-ideal-image/copyUntypedFiles.js
packages/docusaurus-theme-search-algolia/copyUntypedFiles.js packages/docusaurus-theme-search-algolia/copyUntypedFiles.js

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const path = require('path');
const fs = require('fs-extra');
/**
* Copy all untyped and static assets files to lib.
*/
const srcDir = path.resolve(__dirname, 'src');
const libDir = path.resolve(__dirname, 'lib');
fs.copySync(srcDir, libDir, {
filter(filepath) {
return !/__tests__/.test(filepath) && !/\.tsx?$/.test(filepath);
},
});

View file

@ -2,7 +2,14 @@
"name": "@docusaurus/plugin-pwa", "name": "@docusaurus/plugin-pwa",
"version": "2.0.0-beta.9", "version": "2.0.0-beta.9",
"description": "Docusaurus Plugin to add PWA support.", "description": "Docusaurus Plugin to add PWA support.",
"main": "src/index.js", "main": "lib/index.js",
"types": "src/plugin-pwa.d.ts",
"scripts": {
"build": "yarn build:server && yarn build:browser && yarn build:copy",
"build:server": "tsc --project tsconfig.server.json",
"build:browser": "tsc --project tsconfig.browser.json",
"build:copy": "node copyUntypedFiles.js"
},
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
@ -30,6 +37,10 @@
"workbox-precaching": "^6.1.1", "workbox-precaching": "^6.1.1",
"workbox-window": "^6.1.1" "workbox-window": "^6.1.1"
}, },
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.9",
"fs-extra": "^10.0.0"
},
"peerDependencies": { "peerDependencies": {
"@babel/core": "^7.0.0", "@babel/core": "^7.0.0",
"react": "^16.8.4 || ^17.0.0", "react": "^16.8.4 || ^17.0.0",

View file

@ -5,15 +5,17 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
const LogPlugin = import type {HtmlTags, LoadContext, Plugin} from '@docusaurus/types';
require('@docusaurus/core/lib/webpack/plugins/LogPlugin').default; import type {PluginOptions} from '@docusaurus/plugin-pwa';
const {compile} = require('@docusaurus/core/lib/webpack/utils'); import {normalizeUrl} from '@docusaurus/utils';
const {normalizeUrl} = require('@docusaurus/utils'); import {compile} from '@docusaurus/core/lib/webpack/utils';
const path = require('path'); import LogPlugin from '@docusaurus/core/lib/webpack/plugins/LogPlugin';
const webpack = require('webpack');
const {injectManifest} = require('workbox-build'); import path from 'path';
const {PluginOptionSchema} = require('./pluginOptionSchema'); import webpack, {Configuration} from 'webpack';
const Terser = require('terser-webpack-plugin'); import Terser from 'terser-webpack-plugin';
import {injectManifest} from 'workbox-build';
const isProd = process.env.NODE_ENV === 'production'; const isProd = process.env.NODE_ENV === 'production';
@ -43,7 +45,10 @@ function getSWBabelLoader() {
}; };
} }
function plugin(context, options) { export default function (
context: LoadContext,
options: PluginOptions,
): Plugin<void> {
const {outDir, baseUrl} = context; const {outDir, baseUrl} = context;
const { const {
debug, debug,
@ -76,7 +81,7 @@ function plugin(context, options) {
new webpack.EnvironmentPlugin({ new webpack.EnvironmentPlugin({
PWA_DEBUG: debug, PWA_DEBUG: debug,
PWA_SERVICE_WORKER_URL: path.posix.resolve( PWA_SERVICE_WORKER_URL: path.posix.resolve(
`${config.output.publicPath || '/'}`, `${config.output?.publicPath || '/'}`,
'sw.js', 'sw.js',
), ),
PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES: PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES:
@ -88,10 +93,10 @@ function plugin(context, options) {
}, },
injectHtmlTags() { injectHtmlTags() {
const headTags = []; const headTags: HtmlTags = [];
if (isProd && pwaHead) { if (isProd && pwaHead) {
pwaHead.forEach(({tagName, ...attributes}) => { pwaHead.forEach(({tagName, ...attributes}) => {
['href', 'content'].forEach((attribute) => { (['href', 'content'] as const).forEach((attribute) => {
const attributeValue = attributes[attribute]; const attributeValue = attributes[attribute];
if (!attributeValue) { if (!attributeValue) {
@ -122,7 +127,7 @@ function plugin(context, options) {
const swSourceFileTest = /\.m?js$/; const swSourceFileTest = /\.m?js$/;
const swWebpackConfig = { const swWebpackConfig: Configuration = {
entry: path.resolve(__dirname, 'sw.js'), entry: path.resolve(__dirname, 'sw.js'),
output: { output: {
path: outDir, path: outDir,
@ -136,12 +141,13 @@ function plugin(context, options) {
splitChunks: false, splitChunks: false,
minimize: !debug, minimize: !debug,
// see https://developers.google.com/web/tools/workbox/guides/using-bundlers#webpack // see https://developers.google.com/web/tools/workbox/guides/using-bundlers#webpack
minimizer: [ minimizer: debug
!debug && ? []
new Terser({ : [
test: swSourceFileTest, new Terser({
}), test: swSourceFileTest,
].filter(Boolean), }),
],
}, },
plugins: [ plugins: [
new webpack.EnvironmentPlugin({ new webpack.EnvironmentPlugin({
@ -173,6 +179,8 @@ function plugin(context, options) {
'**/*.{js,json,css,html}', '**/*.{js,json,css,html}',
'**/*.{png,jpg,jpeg,gif,svg,ico}', '**/*.{png,jpg,jpeg,gif,svg,ico}',
'**/*.{woff,woff2,eot,ttf,otf}', '**/*.{woff,woff2,eot,ttf,otf}',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...(injectManifest.globPatterns || []), ...(injectManifest.globPatterns || []),
], ],
// those attributes are not overrideable // those attributes are not overrideable
@ -184,8 +192,4 @@ function plugin(context, options) {
}; };
} }
module.exports = plugin; export {validateOptions} from './options';
plugin.validateOptions = function validateOptions({validate, options}) {
return validate(PluginOptionSchema, options);
};

View file

@ -4,9 +4,14 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import path from 'path';
const {Joi} = require('@docusaurus/utils-validation'); import {Joi} from '@docusaurus/utils-validation';
const path = require('path'); import type {
ThemeConfig,
ValidationResult,
OptionValidationContext,
} from '@docusaurus/types';
import type {PluginOptions} from '@docusaurus/plugin-pwa';
const DEFAULT_OPTIONS = { const DEFAULT_OPTIONS = {
debug: false, debug: false,
@ -22,7 +27,7 @@ const DEFAULT_OPTIONS = {
reloadPopup: '@theme/PwaReloadPopup', reloadPopup: '@theme/PwaReloadPopup',
}; };
exports.PluginOptionSchema = Joi.object({ export const Schema = Joi.object({
debug: Joi.bool().default(DEFAULT_OPTIONS.debug), debug: Joi.bool().default(DEFAULT_OPTIONS.debug),
offlineModeActivationStrategies: Joi.array() offlineModeActivationStrategies: Joi.array()
.items( .items(
@ -52,3 +57,10 @@ exports.PluginOptionSchema = Joi.object({
.try(Joi.string(), Joi.bool().valid(false)) .try(Joi.string(), Joi.bool().valid(false))
.default(DEFAULT_OPTIONS.reloadPopup), .default(DEFAULT_OPTIONS.reloadPopup),
}); });
export function validateOptions({
validate,
options,
}: OptionValidationContext<PluginOptions>): ValidationResult<ThemeConfig> {
return validate(Schema, options);
}

View file

@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare module '@docusaurus/plugin-pwa' {
export type pwaHead = {
tagName: string;
href?: string;
content?: string;
[attributeName: string]: string | boolean;
};
export type PluginOptions = {
debug?: boolean;
offlineModeActivationStrategies;
injectManifestConfig;
reloadPopup;
pwaHead: pwaHead[];
swCustom;
swRegister;
};
}
declare module '@theme/PwaReloadPopup' {
export type PwaReloadPopupProps = {
readonly onReload: () => void;
};
const PwaReloadPopup: (props: PwaReloadPopupProps) => JSX.Element;
export default PwaReloadPopup;
}

View file

@ -9,9 +9,11 @@ import React, {useState} from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import Translate, {translate} from '@docusaurus/Translate'; import Translate, {translate} from '@docusaurus/Translate';
import type {PwaReloadPopupProps} from '@theme/PwaReloadPopup';
import styles from './styles.module.css'; import styles from './styles.module.css';
export default function PwaReloadPopup({onReload}) { function PwaReloadPopup({onReload}: PwaReloadPopupProps): JSX.Element | false {
const [isVisible, setIsVisible] = useState(true); const [isVisible, setIsVisible] = useState(true);
return ( return (
@ -56,3 +58,5 @@ export default function PwaReloadPopup({onReload}) {
) )
); );
} }
export default PwaReloadPopup;

View file

@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/// <reference types="@docusaurus/module-type-aliases" />

View file

@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "esnext",
"jsx": "react-native"
},
"include": ["src/theme/", "src/*.d.ts"]
}

View file

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["DOM", "ES2019"],
"rootDir": "src",
"baseUrl": "src",
"outDir": "lib"
}
}

View file

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src/*.ts"]
}

View file

@ -17,7 +17,7 @@ const CodeDirPaths = [
path.join(__dirname, '..', 'docusaurus-theme-common', 'lib'), path.join(__dirname, '..', 'docusaurus-theme-common', 'lib'),
path.join(__dirname, '..', 'docusaurus-theme-search-algolia', 'lib', 'theme'), path.join(__dirname, '..', 'docusaurus-theme-search-algolia', 'lib', 'theme'),
path.join(__dirname, '..', 'docusaurus-theme-live-codeblock', 'src', 'theme'), path.join(__dirname, '..', 'docusaurus-theme-live-codeblock', 'src', 'theme'),
path.join(__dirname, '..', 'docusaurus-plugin-pwa', 'src', 'theme'), path.join(__dirname, '..', 'docusaurus-plugin-pwa', 'lib', 'theme'),
]; ];
console.log('Will scan folders for code translations:', CodeDirPaths); console.log('Will scan folders for code translations:', CodeDirPaths);