diff --git a/package-lock.json b/package-lock.json index 6f80240812c..e5064a5ddc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,6 +62,7 @@ "rimraf": "^2.6.3", "rollup": "^2.79.1", "rollup-plugin-api-extractor": "^0.2.5", + "rollup-plugin-dts": "^4.2.3", "rollup-plugin-flow-no-whitespace": "^1.0.0", "rollup-plugin-typescript2": "^0.34.0", "shelljs": "^0.8.5", @@ -21152,6 +21153,42 @@ "tslib": "*" } }, + "node_modules/rollup-plugin-dts": { + "version": "4.2.3", + "resolved": "https://mirrors.tencent.com/npm/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", + "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "magic-string": "^0.26.6" + }, + "engines": { + "node": ">=v12.22.12" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.18.6" + }, + "peerDependencies": { + "rollup": "^2.55", + "typescript": "^4.1" + } + }, + "node_modules/rollup-plugin-dts/node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://mirrors.tencent.com/npm/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/rollup-plugin-flow-no-whitespace": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rollup-plugin-flow-no-whitespace/-/rollup-plugin-flow-no-whitespace-1.0.0.tgz", @@ -40355,6 +40392,27 @@ "@microsoft/api-extractor": "^7.19.0" } }, + "rollup-plugin-dts": { + "version": "4.2.3", + "resolved": "https://mirrors.tencent.com/npm/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", + "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "magic-string": "^0.26.6" + }, + "dependencies": { + "magic-string": { + "version": "0.26.7", + "resolved": "https://mirrors.tencent.com/npm/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + } + } + }, "rollup-plugin-flow-no-whitespace": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rollup-plugin-flow-no-whitespace/-/rollup-plugin-flow-no-whitespace-1.0.0.tgz", diff --git a/package.json b/package.json index 94d40c59353..16d1d1150d0 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "rimraf": "^2.6.3", "rollup": "^2.79.1", "rollup-plugin-api-extractor": "^0.2.5", + "rollup-plugin-dts": "^4.2.3", "rollup-plugin-flow-no-whitespace": "^1.0.0", "rollup-plugin-typescript2": "^0.34.0", "shelljs": "^0.8.5", diff --git a/packages/hippy-react-web/package-lock.json b/packages/hippy-react-web/package-lock.json index 143fac1bca7..e92abb7fe5e 100644 --- a/packages/hippy-react-web/package-lock.json +++ b/packages/hippy-react-web/package-lock.json @@ -9,8 +9,8 @@ "version": "2.16.0", "license": "Apache-2.0", "dependencies": { - "@hippy/rmc-list-view": ">=1.0.0", - "@hippy/rmc-pull-to-refresh": ">=1.1.1", + "@hippy/rmc-list-view": "^1.0.0", + "@hippy/rmc-pull-to-refresh": "^1.1.1", "animated-scroll-to": "^2.2.0", "bezier-easing": "^2.1.0", "normalize-css-color": "^1.0.2", diff --git a/packages/hippy-react-web/package.json b/packages/hippy-react-web/package.json index fe6176c221c..40ddf5811ce 100644 --- a/packages/hippy-react-web/package.json +++ b/packages/hippy-react-web/package.json @@ -4,6 +4,7 @@ "description": "Web Adapter for Hippy React", "main": "dist/cjs/index.js", "module": "dist/index.js", + "types": "dist/index.d.ts", "homepage": "https://hippyjs.org", "repository": "https://github.com/Tencent/Hippy", "author": "OpenHippy Team", @@ -18,8 +19,8 @@ "Web" ], "dependencies": { - "@hippy/rmc-list-view": ">=1.0.0", - "@hippy/rmc-pull-to-refresh": ">=1.1.1", + "@hippy/rmc-list-view": "^1.0.0", + "@hippy/rmc-pull-to-refresh": "^1.1.1", "animated-scroll-to": "^2.2.0", "bezier-easing": "^2.1.0", "normalize-css-color": "^1.0.2", diff --git a/packages/hippy-react-web/src/adapters/image-loader.ts b/packages/hippy-react-web/src/adapters/image-loader.ts index 3de47f05d20..e6d6755edc8 100644 --- a/packages/hippy-react-web/src/adapters/image-loader.ts +++ b/packages/hippy-react-web/src/adapters/image-loader.ts @@ -34,6 +34,7 @@ const ImageLoader = { image.setAttribute('crossOrigin', 'Anonymous'); image.src = url; image.onerror = (e) => { + // @ts-ignore onError(e); }; image.onload = (e) => { diff --git a/packages/hippy-react-web/src/components/image.tsx b/packages/hippy-react-web/src/components/image.tsx index 2aefaf6275e..48f107a17b4 100644 --- a/packages/hippy-react-web/src/components/image.tsx +++ b/packages/hippy-react-web/src/components/image.tsx @@ -21,15 +21,14 @@ import React, { useState, useEffect, useRef } from 'react'; import { formatWebStyle } from '../adapters/transfer'; import ImageLoader, { LoadError } from '../adapters/image-loader'; -import { LayoutEvent } from '../types'; -import { TouchEvent } from '../modules/use-responder-events/types'; +import { LayoutableProps, TouchableProps, ClickableProps } from '../types'; import useResponderEvents from '../modules/use-responder-events'; import useElementLayout from '../modules/use-element-layout'; import { isFunc, noop } from '../utils'; type ImageResizeMode = 'cover' | 'contain' | 'stretch' | 'center' | 'none'; -export interface ImageProps { +export interface ImageProps extends LayoutableProps, TouchableProps, ClickableProps { [key: string]: any; style: HippyTypes.Style; tintColor?: HippyTypes.color; @@ -40,14 +39,9 @@ export interface ImageProps { capInsets?: any; resizeMode?: ImageResizeMode; onLoad?: (e: { width: number; height: number; url: string }) => void; - onLayout?: (e: LayoutEvent) => void; onLoadStart?: Function; onLoadEnd?: Function; onProgress?: Function; - onTouchDown?: (e: TouchEvent) => void; - onTouchMove?: (e: TouchEvent) => void; - onTouchEnd?: (e: TouchEvent) => void; - onTouchCancel?: (e: TouchEvent) => void; } const ImageResizeMode = { diff --git a/packages/hippy-react-web/src/components/list-view.tsx b/packages/hippy-react-web/src/components/list-view.tsx index fd668efad1c..1e500579764 100644 --- a/packages/hippy-react-web/src/components/list-view.tsx +++ b/packages/hippy-react-web/src/components/list-view.tsx @@ -32,7 +32,7 @@ import View from './view'; interface ListViewItemProps { style?: any; - height: any; + height?: any; children?: any; type?: any; observer?: IntersectionObserver | null; @@ -142,6 +142,7 @@ function ListViewItem(props: ListViewItemProps) { delete liElementProps.rowShouldSticky; return ( + // @ts-ignore
  • ); } diff --git a/packages/hippy-react-web/src/components/text-input.tsx b/packages/hippy-react-web/src/components/text-input.tsx index 2d71c7a0e77..c805c655752 100644 --- a/packages/hippy-react-web/src/components/text-input.tsx +++ b/packages/hippy-react-web/src/components/text-input.tsx @@ -21,7 +21,7 @@ /* eslint-disable no-unneeded-ternary */ import React, { useImperativeHandle, useEffect, useRef } from 'react'; - +import { LayoutableProps, ClickableProps } from '../types'; import { formatWebStyle } from '../adapters/transfer'; import useElementLayout from '../modules/use-element-layout'; import { isFunc } from '../utils'; @@ -32,7 +32,7 @@ import { isFunc } from '../utils'; * placeholder text, and different keyboard types, such as a numeric keypad. * @noInheritDoc */ -export interface TextInputProps { +export interface TextInputProps extends LayoutableProps, ClickableProps { style?: HippyTypes.Style; caretColor?: string; defaultValue?: string; @@ -52,7 +52,6 @@ export interface TextInputProps { onChangeText?: any; onKeyboardWillShow?: any; onEndEditing?: any; - onLayout?: any; onSelectionChange?: any; }; const TextInput: React.FC = React.forwardRef((props, ref) => { diff --git a/packages/hippy-react-web/src/components/text.tsx b/packages/hippy-react-web/src/components/text.tsx index df6ead10190..13578beda77 100644 --- a/packages/hippy-react-web/src/components/text.tsx +++ b/packages/hippy-react-web/src/components/text.tsx @@ -21,10 +21,9 @@ // @ts-nocheck import React, { createContext, useRef } from 'react'; import { formatWebStyle } from '../adapters/transfer'; -import { LayoutEvent } from '../types'; +import { LayoutableProps, TouchableProps, ClickableProps } from '../types'; import useResponderEvents from '../modules/use-responder-events'; import useElementLayout from '../modules/use-element-layout'; -import { TouchEvent } from '../modules/use-responder-events/types'; import { DEFAULT_CONTAINER_STYLE } from '../constants'; const baseTextStyle = { @@ -71,16 +70,11 @@ const styles = { const TextAncestorContext = createContext(false); -interface TextProps { +interface TextProps extends LayoutableProps, TouchableProps, ClickableProps { style?: HippyTypes.Style | HippyTypes.Style[]; numberOfLines?: number; opacity?: number; ellipsizeMode?: 'clip' | 'ellipsis'; - onLayout: (e: LayoutEvent) => void; - onTouchDown?: (e: TouchEvent) => void; - onTouchMove?: (e: TouchEvent) => void; - onTouchEnd?: (e: TouchEvent) => void; - onTouchCancel?: (e: TouchEvent) => void; } /** diff --git a/packages/hippy-react-web/src/components/view.tsx b/packages/hippy-react-web/src/components/view.tsx index ae8b8be5288..86256fcca53 100644 --- a/packages/hippy-react-web/src/components/view.tsx +++ b/packages/hippy-react-web/src/components/view.tsx @@ -21,8 +21,7 @@ import React, { useEffect, useRef, useImperativeHandle } from 'react'; import { formatWebStyle } from '../adapters/transfer'; import useResponderEvents from '../modules/use-responder-events'; import useElementLayout from '../modules/use-element-layout'; -import { TouchEvent } from '../modules/use-responder-events/types'; -import { LayoutEvent } from '../types'; +import { LayoutableProps, TouchableProps, ClickableProps } from '../types'; import { warn } from '../utils'; import { DEFAULT_CONTAINER_STYLE } from '../constants'; @@ -40,7 +39,7 @@ const styles = { }, }; -interface ViewProps { +interface ViewProps extends LayoutableProps, TouchableProps, ClickableProps { [key: string]: any; ref?: any; accessible?: boolean; @@ -55,12 +54,7 @@ interface ViewProps { rippleRadius: number; }; onScroll?: (e: any) => void; - onLayout?: (e: LayoutEvent) => void; onAttachedToWindow?: Function; - onTouchDown?: (e: TouchEvent) => void; - onTouchMove?: (e: TouchEvent) => void; - onTouchEnd?: (e: TouchEvent) => void; - onTouchCancel?: (e: TouchEvent) => void; } /** diff --git a/packages/hippy-react-web/src/modules/use-responder-events/index.ts b/packages/hippy-react-web/src/modules/use-responder-events/index.ts index 7e3506ce2f5..80a614b71b2 100644 --- a/packages/hippy-react-web/src/modules/use-responder-events/index.ts +++ b/packages/hippy-react-web/src/modules/use-responder-events/index.ts @@ -20,16 +20,12 @@ import React from 'react'; import { useStable } from '../../utils'; +import { TouchableProps } from '../../types'; import ResponderEvent from './responder-events'; -import { TouchEvent } from './types'; let idCounter = 0; -export interface ResponderConfig { - onTouchDown?: (e: TouchEvent) => void; - onTouchMove?: (e: TouchEvent) => void; - onTouchEnd?: (e: TouchEvent) => void; - onTouchCancel?: (e: TouchEvent) => void; +export interface ResponderConfig extends TouchableProps { onScroll?: (e: any) => void; }; diff --git a/packages/hippy-react-web/src/modules/use-responder-events/responder-events.ts b/packages/hippy-react-web/src/modules/use-responder-events/responder-events.ts index cd3ff946358..b2eb98385e1 100644 --- a/packages/hippy-react-web/src/modules/use-responder-events/responder-events.ts +++ b/packages/hippy-react-web/src/modules/use-responder-events/responder-events.ts @@ -19,11 +19,11 @@ */ import { canUseDOM } from '../../utils'; +import { TouchEvent } from '../../types'; import { getResponderPaths, setResponderId, TOUCH_CANCEL, TOUCH_END, TOUCH_MOVE, TOUCH_START, SCROLL_EVENT, isScrollEvent, } from './utils'; -import { TouchEvent } from './types'; import { ResponderConfig } from './index'; interface ResponderEvent { diff --git a/packages/hippy-react-web/src/modules/use-responder-events/types.ts b/packages/hippy-react-web/src/modules/use-responder-events/types.ts deleted file mode 100644 index 98253c6d711..00000000000 --- a/packages/hippy-react-web/src/modules/use-responder-events/types.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2017-2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface TouchEvent { - pageX: number; - pageY: number; - target: any; - currentTarget: any; - force: number; - identifier: number; - stopPropagation: () => void; -}; diff --git a/packages/hippy-react-web/src/types/index.ts b/packages/hippy-react-web/src/types/index.ts index c0bc3f63f83..2c669bdd555 100644 --- a/packages/hippy-react-web/src/types/index.ts +++ b/packages/hippy-react-web/src/types/index.ts @@ -17,6 +17,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +export interface TouchEvent { + pageX: number; + pageY: number; + target: any; + currentTarget: any; + force: number; + identifier: number; + stopPropagation: () => void; +}; export interface LayoutValue { x: number, @@ -50,3 +59,21 @@ export interface NetInfoModule { removeEventListener: (eventName: string, listener?: NetworkInfoCallback) => void; fetch: () => Promise; }; + +export interface LayoutableProps { + onLayout?: (evt: LayoutEvent) => void; +} + +export interface ClickableProps { + /** + * Called when the touch is released. + */ + onClick?: () => void; +} + +export interface TouchableProps { + onTouchDown?: (e: TouchEvent) => void; + onTouchMove?: (e: TouchEvent) => void; + onTouchEnd?: (e: TouchEvent) => void; + onTouchCancel?: (e: TouchEvent) => void; +} diff --git a/scripts/build.js b/scripts/build.js index 43db01778a6..03129bec15c 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -22,10 +22,11 @@ const path = require('path'); const fs = require('fs'); const { rollup } = require('rollup'); const reactBuilds = require('./react-configs').getAllBuilds(); +const reactWebBuilds = require('./react-web-configs').getAllBuilds(); const vueBuilds = require('./vue-configs').getAllBuilds(); const vueNextBuilds = require('./vue-next-configs').getAllBuilds(); const webRendererBuilds = require('./web-renderer-configs').getAllBuilds(); -let builds = [...reactBuilds, ...vueBuilds, ...vueNextBuilds, ...webRendererBuilds]; +let builds = [...reactBuilds, ...reactWebBuilds, ...vueBuilds, ...vueNextBuilds, ...webRendererBuilds]; // filter builds via command line arg if (process.argv[2]) { @@ -50,7 +51,7 @@ function logError(e) { * remove typescript declaration files that generated by rollup plugin. * * 1. auto generate typescript declaration files by rollup-plugin-typescript2 - * 2. declaration files rollup to index.d.ts by api-extractor + * 2. declaration files rollup to index.d.ts by rollup-plugin-dts * 3. remove auto generated declaration files * * @param filePath diff --git a/scripts/react-configs.js b/scripts/react-configs.js index 10bcd9ec850..a17e72bddaf 100644 --- a/scripts/react-configs.js +++ b/scripts/react-configs.js @@ -19,72 +19,12 @@ */ const path = require('path'); -const fs = require('fs'); const typescript = require('rollup-plugin-typescript2'); const replace = require('@rollup/plugin-replace'); -// const alias = require('@rollup/plugin-alias'); const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const { babel, getBabelOutputPlugin } = require('@rollup/plugin-babel'); const commonjs = require('@rollup/plugin-commonjs'); const hippyReactPackage = require('../packages/hippy-react/package.json'); -const hippyReactWebPackage = require('../packages/hippy-react-web/package.json'); - -function banner(name, version) { - const startYear = 2017; - const thisYear = new Date().getFullYear(); - let copyRightYears = thisYear; - if (startYear !== thisYear) { - copyRightYears = `${startYear}-${thisYear}`; - } - - return `/*! - * ${name} v${version} - * Build at: ${new Date()} - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) ${copyRightYears} THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -`; -} - -const hippyReactWebPath = path.resolve(__dirname, '../packages/hippy-react-web'); -const hippyReactWebComponentsPath = `${hippyReactWebPath}/src/components`; -const hippyReactWebModulesPath = `${hippyReactWebPath}/src/modules`; -const getHippyReactWebModules = () => { - const hippyReactWebmodules = []; - fs.readdirSync(hippyReactWebModulesPath).forEach((file) => { - const moduleFilePath = `${hippyReactWebModulesPath}/${file}`; - if (fs.lstatSync(moduleFilePath).isDirectory()) { - if (fs.lstatSync(`${moduleFilePath}/index.ts`).isFile()) { - hippyReactWebmodules.push(`${moduleFilePath}/index.ts`); - } - } else { - hippyReactWebmodules.push(moduleFilePath); - } - }); - return hippyReactWebmodules; -}; -const hippyReactWebComponents = fs.readdirSync(hippyReactWebComponentsPath).map(filename => `${hippyReactWebComponentsPath}/${filename}`); -const hippyReactWebModules = getHippyReactWebModules(); - -function resolvePackage(src, extra = 'src') { - return path.resolve(__dirname, '../packages/', src, extra); -} +const { banner, resolvePackage } = require('./utils'); const builds = { '@hippy/react': { @@ -100,78 +40,6 @@ const builds = { ].find(ext => id.startsWith(ext)); }, }, - '@hippy/react-web': { - entry: [ - resolvePackage('hippy-react-web', 'src/index.ts'), - ...hippyReactWebComponents, - ...hippyReactWebModules, - ], - dest: resolvePackage('hippy-react-web', 'dist/index.js'), - format: 'es', - banner: banner('@hippy/react-web', hippyReactWebPackage.version), - plugins: [ - babel({ babelHelpers: 'bundled' }), - ], - output: { - dir: './packages/hippy-react-web/dist', - format: 'es', - entryFileNames: (bundle) => { - if (bundle.facadeModuleId.includes('src/index.ts')) return '[name].js'; - if (bundle.facadeModuleId.includes('src/modules/')) return 'modules/[name].js'; - return 'lib/[name].js'; - }, - chunkFileNames: 'chunk/[name].[hash].js', - plugins: [ - getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), - ], - }, - external(id) { - return !![ - 'react', - 'react-dom', - 'swiper', - '@hippy/rmc-list-view', - '@hippy/rmc-pull-to-refresh', - ].find(ext => id.startsWith(ext)); - }, - onwarn(warning) { - // ignore warning from package 'rmc-pull-to-refresh' - if (warning.code === 'THIS_IS_UNDEFINED') { - return; - } - }, - }, - '@hippy/react-web-cjs': { - entry: resolvePackage('hippy-react-web', 'src/index.ts'), - format: 'es', - banner: banner('@hippy/react-web', hippyReactWebPackage.version), - plugins: [ - babel({ babelHelpers: 'bundled' }), - ], - output: { - dir: resolvePackage('hippy-react-web', 'dist/cjs'), - filename: 'index.js', - format: 'cjs', - plugins: [ - getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), - ], - }, - external(id) { - return !![ - 'react', - 'react-dom', - 'swiper', - '@hippy/rmc-list-view', - '@hippy/rmc-pull-to-refresh', - ].find(ext => id.startsWith(ext)); - }, - onwarn(warning) { - // ignore warning from package 'rmc-pull-to-refresh' - if (warning.code === 'THIS_IS_UNDEFINED') { - return; - } - }, - }, }; function genConfig(name) { @@ -184,7 +52,6 @@ function genConfig(name) { preventAssignment: true, values: { 'process.env.HIPPY_REACT_VERSION': `"${hippyReactPackage.version}"`, - 'process.env.HIPPY_REACT_WEB_VERSION': `"${hippyReactWebPackage.version}"`, }, }), nodeResolve(), @@ -194,11 +61,10 @@ function genConfig(name) { tsconfigOverride: { compilerOptions: { declaration: false, - declarationMap: false, }, exclude: ['**/__tests__/*.test.*'], include: [ - 'packages/hippy-react*/src', + 'packages/hippy-react/src', 'packages/global.d.ts', 'node_modules/@types/web/index.d.ts', 'node_modules/@types/node/index.d.ts', diff --git a/scripts/react-web-configs.js b/scripts/react-web-configs.js new file mode 100644 index 00000000000..b173494724a --- /dev/null +++ b/scripts/react-web-configs.js @@ -0,0 +1,180 @@ +/* + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const path = require('path'); +const fs = require('fs'); +const typescript = require('rollup-plugin-typescript2'); +const replace = require('@rollup/plugin-replace'); +const dts = require('rollup-plugin-dts').default; +const { nodeResolve } = require('@rollup/plugin-node-resolve'); +const { babel, getBabelOutputPlugin } = require('@rollup/plugin-babel'); +const commonjs = require('@rollup/plugin-commonjs'); +const hippyReactWebPackage = require('../packages/hippy-react-web/package.json'); +const { banner, resolvePackage, getDtsConfig } = require('./utils'); + + +const hippyReactWebPath = path.resolve(__dirname, '../packages/hippy-react-web'); +const hippyReactWebComponentsPath = `${hippyReactWebPath}/src/components`; +const hippyReactWebModulesPath = `${hippyReactWebPath}/src/modules`; +const getHippyReactWebModules = () => { + const hippyReactWebmodules = []; + fs.readdirSync(hippyReactWebModulesPath).forEach((file) => { + const moduleFilePath = `${hippyReactWebModulesPath}/${file}`; + if (fs.lstatSync(moduleFilePath).isDirectory()) { + if (fs.lstatSync(`${moduleFilePath}/index.ts`).isFile()) { + hippyReactWebmodules.push(`${moduleFilePath}/index.ts`); + } + } else { + hippyReactWebmodules.push(moduleFilePath); + } + }); + return hippyReactWebmodules; +}; +const hippyReactWebComponents = fs.readdirSync(hippyReactWebComponentsPath).map(filename => `${hippyReactWebComponentsPath}/${filename}`); +const hippyReactWebModules = getHippyReactWebModules(); + +const builds = { + '@hippy/react-web': { + entry: [ + resolvePackage('hippy-react-web', 'src/index.ts'), + ...hippyReactWebComponents, + ...hippyReactWebModules, + ], + dest: resolvePackage('hippy-react-web', 'dist/index.js'), + format: 'es', + banner: banner('@hippy/react-web', hippyReactWebPackage.version), + plugins: [ + babel({ babelHelpers: 'bundled' }), + ], + output: { + dir: './packages/hippy-react-web/dist', + format: 'es', + entryFileNames: (bundle) => { + if (bundle.facadeModuleId.includes('src/index.ts')) return '[name].js'; + if (bundle.facadeModuleId.includes('src/modules/')) return 'modules/[name].js'; + return 'lib/[name].js'; + }, + chunkFileNames: 'chunk/[name].[hash].js', + plugins: [ + getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), + ], + }, + external(id) { + return !![ + 'react', + 'react-dom', + 'swiper', + '@hippy/rmc-list-view', + '@hippy/rmc-pull-to-refresh', + ].find(ext => id.startsWith(ext)); + }, + }, + '@hippy/react-web-cjs': { + entry: resolvePackage('hippy-react-web', 'src/index.ts'), + format: 'es', + banner: banner('@hippy/react-web', hippyReactWebPackage.version), + plugins: [ + babel({ babelHelpers: 'bundled' }), + ], + output: { + dir: resolvePackage('hippy-react-web', 'dist/cjs'), + format: 'cjs', + plugins: [ + getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), + ], + }, + external(id) { + return !![ + 'react', + 'react-dom', + 'swiper', + '@hippy/rmc-list-view', + '@hippy/rmc-pull-to-refresh', + ].find(ext => id.startsWith(ext)); + }, + }, +}; + +builds.declaration = getDtsConfig(builds['@hippy/react-web']); + +function genConfig(name) { + const opts = builds[name]; + // declaration + if (name === 'declaration') { + return opts; + } + const config = { + input: opts.entry, + external: opts.external, + plugins: [ + replace({ + preventAssignment: true, + values: { + 'process.env.HIPPY_REACT_WEB_VERSION': `"${hippyReactWebPackage.version}"`, + }, + }), + nodeResolve(), + commonjs(), + typescript({ + tsconfig: path.resolve(__dirname, '../tsconfig.json'), + tsconfigOverride: { + compilerOptions: { + declaration: false, + }, + exclude: ['**/__tests__/*.test.*'], + include: [ + 'packages/hippy-react-web/src', + 'packages/global.d.ts', + 'node_modules/@types/web/index.d.ts', + 'node_modules/@types/node/index.d.ts', + ], + }, + }), + ].concat(opts.plugins || []), + output: opts?.output ? opts.output : { + name, + file: opts.dest, + format: opts.format, + banner: opts.banner, + exports: 'auto', + }, + onwarn: (msg) => { + // ignore warning from package 'rmc-pull-to-refresh' + if (msg.code === 'THIS_IS_UNDEFINED') { + return; + } + }, + }; + + if (opts.env) { + config.plugins.push(replace({ + 'process.env.NODE_ENV': JSON.stringify(opts.env), + })); + } + + return config; +} + +if (process.env.TARGET) { + module.exports = genConfig(process.env.TARGET); +} else { + module.exports.getBuild = genConfig; + module.exports.getAllBuilds = () => Object.keys(builds).map(genConfig); +} diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644 index 00000000000..230de5a008a --- /dev/null +++ b/scripts/utils.js @@ -0,0 +1,76 @@ +/* + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const path = require('path'); +const dts = require('rollup-plugin-dts').default; + +function banner(name, version, extra = '', startYear = 2017) { + const thisYear = new Date().getFullYear(); + let copyRightYears = thisYear; + if (startYear !== thisYear) { + copyRightYears = `${startYear}-${thisYear}`; + } + + return `/*! + * ${name} v${version}${extra} + * Build at: ${new Date()} + * + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) ${copyRightYears} THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +`; +}; + + +function resolvePackage(src, extra = 'src') { + return path.resolve(__dirname, '../packages/', src, extra); +} + +function getDtsConfig(config) { + return { + input: Array.isArray(config.entry) ? config.entry[0] : config.entry, + output: { + file: config.dest.replace('.js', '.d.ts'), + format: 'es', + }, + external: config.external, + plugins: [dts()], + }; +} + +module.exports = { + banner, + resolvePackage, + getDtsConfig, +}; diff --git a/scripts/vue-configs.js b/scripts/vue-configs.js index f195fd82e40..1075708d705 100644 --- a/scripts/vue-configs.js +++ b/scripts/vue-configs.js @@ -31,51 +31,15 @@ const hippyVuePackage = require('../packages/hippy-vue/package.json'); const cssLoaderPackage = require('../packages/hippy-vue-css-loader/package.json'); const nativeComponentsPackage = require('../packages/hippy-vue-native-components/package.json'); const routerPackage = require('../packages/hippy-vue-router/package.json'); +const { banner, resolvePackage } = require('./utils'); +const bannerStr = `\n * (Using Vue v${VueVersion})`; +const bannerStrAndHippyVueString = `\n * (Using Vue v${VueVersion} and Hippy-Vue v${hippyVuePackage.version})`; -const andHippyVueString = ` and Hippy-Vue v${hippyVuePackage.version}`; - -function banner(name, version) { - const startYear = 2017; - const thisYear = new Date().getFullYear(); - let copyRightYears = thisYear; - if (startYear !== thisYear) { - copyRightYears = `${startYear}-${thisYear}`; - } - - return `/*! - * ${name} v${version} - * (Using Vue v${VueVersion}${name !== '@hippy/vue' ? andHippyVueString : ''}) - * Build at: ${new Date()} - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) ${copyRightYears} THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -`; -} function resolveVue(p) { return path.resolve(__dirname, '../node_modules/vue/src/', p); } -function resolvePackage(src, extra = 'src') { - return path.resolve(__dirname, '../packages/', src, extra); -} - const aliases = { vue: resolveVue('core/index'), compiler: resolveVue('compiler'), @@ -95,7 +59,7 @@ const builds = { entry: resolvePackage('hippy-vue', 'src/index.js'), dest: resolvePackage('hippy-vue', 'dist/index.js'), format: 'es', - banner: banner('@hippy/vue', hippyVuePackage.version), + banner: banner('@hippy/vue', hippyVuePackage.version, bannerStr), }, '@hippy/vue-css-loader': { entry: { @@ -106,7 +70,7 @@ const builds = { entryFileNames: '[name].js', format: 'cjs', moduleName: 'hippy-vue-css-loader', - banner: banner('@hippy/vue-css-loader', cssLoaderPackage.version), + banner: banner('@hippy/vue-css-loader', cssLoaderPackage.version, bannerStrAndHippyVueString), external(id) { return id in Object.keys(cssLoaderPackage.dependencies); }, @@ -116,14 +80,14 @@ const builds = { dest: resolvePackage('hippy-vue-native-components', 'dist/index.js'), format: 'es', moduleName: 'hippy-vue-native-components', - banner: banner('@hippy/vue-native-components', nativeComponentsPackage.version), + banner: banner('@hippy/vue-native-components', nativeComponentsPackage.version, bannerStrAndHippyVueString), }, '@hippy/vue-router': { entry: resolvePackage('hippy-vue-router', 'src/index.js'), dest: resolvePackage('hippy-vue-router', 'dist/index.js'), format: 'es', moduleName: 'hippy-vue-router', - banner: banner('@hippy/vue-router', routerPackage.version), + banner: banner('@hippy/vue-router', routerPackage.version, bannerStrAndHippyVueString), }, }; diff --git a/scripts/vue-next-configs.js b/scripts/vue-next-configs.js index be22e939a02..0290b73a6d6 100644 --- a/scripts/vue-next-configs.js +++ b/scripts/vue-next-configs.js @@ -29,46 +29,8 @@ const { apiExtractor } = require('rollup-plugin-api-extractor'); const VueVersion = require('../packages/hippy-vue-next/node_modules/@vue/runtime-core/package.json').version; const hippyVueNextPackage = require('../packages/hippy-vue-next/package.json'); const hippyStyleParserPackage = require('../packages/hippy-vue-next-style-parser/package.json'); - -const andHippyVueNextString = ` and Hippy-Vue-Next v${hippyVueNextPackage.version}`; - -function banner(name, version) { - const startYear = 2022; - const thisYear = new Date().getFullYear(); - let copyRightYears = thisYear; - if (startYear !== thisYear) { - copyRightYears = `${startYear}-${thisYear}`; - } - - return `/*! - * ${name} v${version} - * (Using Vue v${VueVersion}${name !== '@hippy/vue-next' ? andHippyVueNextString : ''}) - * Build at: ${new Date()} - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) ${copyRightYears} THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -`; -} - -function resolvePackage(src, extra = 'src') { - return path.resolve(__dirname, '../packages/', src, extra); -} +const { banner, resolvePackage } = require('./utils'); +const bannerStrAndHippyVueString = `\n * (Using Vue v${VueVersion} and Hippy-Vue-Next v${hippyVueNextPackage.version})`; const builds = { '@hippy/hippy-vue-next-style-parser': { @@ -76,13 +38,13 @@ const builds = { dest: resolvePackage('hippy-vue-next-style-parser', 'dist/index.js'), format: 'cjs', moduleName: 'hippy-vue-next-style-parser', - banner: banner('@hippy/hippy-vue-next-style-parser', hippyStyleParserPackage.version), + banner: banner('@hippy/hippy-vue-next-style-parser', hippyStyleParserPackage.version, bannerStrAndHippyVueString, 2022), }, '@hippy/vue-next': { entry: resolvePackage('hippy-vue-next', 'src/index.ts'), dest: resolvePackage('hippy-vue-next', 'dist/index.js'), format: 'es', - banner: banner('@hippy/vue', hippyVueNextPackage.version), + banner: banner('@hippy/vue', hippyVueNextPackage.version, bannerStrAndHippyVueString, 2022), name: 'hippy-vue-next', external: ['@vue/runtime-core'], }, diff --git a/scripts/web-renderer-configs.js b/scripts/web-renderer-configs.js index ef97fb79782..5a224988513 100644 --- a/scripts/web-renderer-configs.js +++ b/scripts/web-renderer-configs.js @@ -25,38 +25,7 @@ const { nodeResolve } = require('@rollup/plugin-node-resolve'); const commonjs = require('@rollup/plugin-commonjs'); const { babel } = require('@rollup/plugin-babel'); const hippyWebRendererPackage = require('../packages/hippy-web-renderer/package.json'); -function banner(name, version) { - const startYear = 2017; - const thisYear = new Date().getFullYear(); - let copyRightYears = thisYear; - if (startYear !== thisYear) { - copyRightYears = `${startYear}-${thisYear}`; - } - - return `/*! - * ${name} v${version} - * Build at: ${new Date()} - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) ${copyRightYears} THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -`; -} +const { banner } = require('./utils'); const builds = { '@hippy/web-renderer': {