feat: update vue-adapter
This commit is contained in:
parent
b725b0d98c
commit
0f75e48f79
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
||||
tabWidth: 2, // tab等2个空格
|
||||
useTabs: false, // 用空格缩进行
|
||||
semi: true, // 行尾使用分号
|
||||
singleQuote: true, // 字符串使用单引号
|
||||
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
||||
jsxSingleQuote: false, // 在JSX中使用双引号
|
||||
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
||||
bracketSpacing: true, // 对象的括号间增加空格
|
||||
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
||||
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
||||
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
||||
endOfLine: 'lf', // 仅限换行(\n)
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
presets: ['@babel/preset-typescript', ['@babel/preset-env', { targets: { node: 'current' } }]],
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-jsx',
|
||||
[
|
||||
'@babel/plugin-transform-react-jsx',
|
||||
{
|
||||
runtime: 'automatic',
|
||||
importSource: 'openinula',
|
||||
},
|
||||
],
|
||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||
['@babel/plugin-proposal-private-methods', { loose: true }],
|
||||
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
||||
'@babel/plugin-transform-object-assign',
|
||||
'@babel/plugin-transform-object-super',
|
||||
['@babel/plugin-proposal-object-rest-spread', { loose: true, useBuiltIns: true }],
|
||||
['@babel/plugin-transform-template-literals', { loose: true }],
|
||||
'@babel/plugin-transform-arrow-functions',
|
||||
'@babel/plugin-transform-literals',
|
||||
'@babel/plugin-transform-for-of',
|
||||
'@babel/plugin-transform-block-scoped-functions',
|
||||
'@babel/plugin-transform-classes',
|
||||
'@babel/plugin-transform-shorthand-properties',
|
||||
'@babel/plugin-transform-computed-properties',
|
||||
'@babel/plugin-transform-parameters',
|
||||
['@babel/plugin-transform-spread', { loose: true, useBuiltIns: true }],
|
||||
['@babel/plugin-transform-block-scoping', { throwIfClosureRequired: false }],
|
||||
['@babel/plugin-transform-destructuring', { loose: true, useBuiltIns: true }],
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-proposal-nullish-coalescing-operator',
|
||||
'@babel/plugin-proposal-optional-chaining',
|
||||
],
|
||||
};
|
|
@ -2,18 +2,60 @@
|
|||
"name": "@inula/vue-adapter",
|
||||
"version": "0.0.1",
|
||||
"description": "vue adapter",
|
||||
"main": "./src/index.ts",
|
||||
"main": "./build/cjs/vue-adapter.js",
|
||||
"module": "./build/esm/vue-adapter.js",
|
||||
"types": "build/@types/index.d.ts",
|
||||
"files": [
|
||||
"/build",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "vitest --ui"
|
||||
"test": "vitest --ui",
|
||||
"build": "rollup -c ./scripts/rollup.config.js && npm run build-types",
|
||||
"build-types": "tsc -p tsconfig.build.json && rollup -c ./scripts/build-types.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"openinula": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"@babel/core": "7.21.3",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.16.7",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
||||
"@babel/plugin-syntax-jsx": "7.16.7",
|
||||
"@babel/plugin-transform-arrow-functions": "7.16.7",
|
||||
"@babel/plugin-transform-block-scoped-functions": "7.16.7",
|
||||
"@babel/plugin-transform-block-scoping": "7.16.7",
|
||||
"@babel/plugin-transform-classes": "7.16.7",
|
||||
"@babel/plugin-transform-computed-properties": "7.16.7",
|
||||
"@babel/plugin-transform-destructuring": "7.16.7",
|
||||
"@babel/plugin-transform-for-of": "7.16.7",
|
||||
"@babel/plugin-transform-literals": "7.16.7",
|
||||
"@babel/plugin-transform-object-assign": "7.16.7",
|
||||
"@babel/plugin-transform-object-super": "7.16.7",
|
||||
"@babel/plugin-transform-parameters": "7.16.7",
|
||||
"@babel/plugin-transform-react-jsx": "7.16.7",
|
||||
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
|
||||
"@babel/plugin-transform-runtime": "7.16.7",
|
||||
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
||||
"@babel/plugin-transform-spread": "7.16.7",
|
||||
"@babel/plugin-transform-template-literals": "7.16.7",
|
||||
"@babel/preset-env": "7.16.7",
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"prettier": "2.8.8",
|
||||
"rollup": "2.79.1",
|
||||
"rollup-plugin-dts": "^6.0.1",
|
||||
"rollup-plugin-terser": "^5.1.3",
|
||||
"typescript": "4.9.3",
|
||||
"@vitest/ui": "^0.34.5",
|
||||
"jsdom": "^24.0.0",
|
||||
"vitest": "^0.34.5",
|
||||
"@vitejs/plugin-react": "^4.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openinula": ">=0.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import dts from 'rollup-plugin-dts';
|
||||
|
||||
function deleteFolder(filePath) {
|
||||
if (fs.existsSync(filePath)) {
|
||||
if (fs.lstatSync(filePath).isDirectory()) {
|
||||
const files = fs.readdirSync(filePath);
|
||||
files.forEach(file => {
|
||||
const nextFilePath = path.join(filePath, file);
|
||||
const states = fs.lstatSync(nextFilePath);
|
||||
if (states.isDirectory()) {
|
||||
deleteFolder(nextFilePath);
|
||||
} else {
|
||||
fs.unlinkSync(nextFilePath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(filePath);
|
||||
} else if (fs.lstatSync(filePath).isFile()) {
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除非空文件夹
|
||||
* @param folders {string[]}
|
||||
* @returns {{buildEnd(): void, name: string}}
|
||||
*/
|
||||
export function cleanUp(folders) {
|
||||
return {
|
||||
name: 'clean-up',
|
||||
buildEnd() {
|
||||
folders.forEach(f => deleteFolder(f));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildTypeConfig() {
|
||||
return {
|
||||
input: ['./build/@types/index.d.ts'],
|
||||
output: {
|
||||
file: './build/@types/index.d.ts',
|
||||
},
|
||||
plugins: [dts(), cleanUp(['./build/@types/'])],
|
||||
};
|
||||
}
|
||||
|
||||
export default [buildTypeConfig()];
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
|
||||
const rootDir = path.join(__dirname, '..');
|
||||
const outDir = path.join(rootDir, 'build');
|
||||
|
||||
const extensions = ['.js', '.ts', '.tsx'];
|
||||
|
||||
if (!fs.existsSync(outDir)) {
|
||||
fs.mkdirSync(outDir, { recursive: true });
|
||||
}
|
||||
|
||||
const getConfig = mode => {
|
||||
const prod = mode.startsWith('prod');
|
||||
const outputList = [
|
||||
{
|
||||
file: path.join(outDir, `cjs/vue-adapter.${prod ? 'min.' : ''}js`),
|
||||
sourcemap: 'true',
|
||||
format: 'cjs',
|
||||
},
|
||||
{
|
||||
file: path.join(outDir, `umd/vue-adapter.${prod ? 'min.' : ''}js`),
|
||||
name: 'VueAdapter',
|
||||
sourcemap: 'true',
|
||||
format: 'umd',
|
||||
},
|
||||
];
|
||||
if (!prod) {
|
||||
outputList.push({
|
||||
file: path.join(outDir, 'esm/vue-adapter.js'),
|
||||
sourcemap: 'true',
|
||||
format: 'esm',
|
||||
});
|
||||
}
|
||||
return {
|
||||
input: path.join(rootDir, '/src/index.ts'),
|
||||
output: outputList,
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions,
|
||||
modulesOnly: true,
|
||||
}),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
configFile: path.join(rootDir, '/babel.config.js'),
|
||||
babelHelpers: 'runtime',
|
||||
extensions,
|
||||
}),
|
||||
prod && terser(),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
export default [getConfig('dev'), getConfig('prod')];
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
|
|
|
@ -23,7 +23,7 @@ const useIsMounted = () => {
|
|||
isMounted.current = false;
|
||||
};
|
||||
}, []);
|
||||
return isMounted;
|
||||
return isMounted.current;
|
||||
};
|
||||
|
||||
export const onBeforeMount = (fn: () => void) => {
|
||||
|
|
|
@ -17,9 +17,113 @@
|
|||
|
||||
import { describe, it, vi, expect } from 'vitest';
|
||||
import { render, act, useState } from 'openinula';
|
||||
import { onBeforeUnmount } from '../src';
|
||||
import { onBeforeUnmount, onUnmounted, onMounted, onBeforeMount, onUpdated } from '../src';
|
||||
|
||||
describe('lifecycle', () => {
|
||||
it('should call the onBeforeMount', () => {
|
||||
const fn = vi.fn(() => {
|
||||
expect(document.querySelector('span')).toBeNull();
|
||||
});
|
||||
|
||||
const Comp = () => {
|
||||
const [toggle, setToggle] = useState(true);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggle ? <Child /> : null}
|
||||
<button onClick={() => setToggle(false)}>Unmount</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Child = () => {
|
||||
onBeforeMount(fn);
|
||||
return <span />;
|
||||
};
|
||||
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
render(<Comp />, container);
|
||||
|
||||
expect(document.querySelector('span')).not.toBeNull();
|
||||
|
||||
act(() => {
|
||||
container.querySelector('button').dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
});
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should call the onMounted', () => {
|
||||
const fn = vi.fn(() => {
|
||||
// 断言在组件卸载之后,子组件不存在于 DOM 中
|
||||
expect(document.querySelector('span')).not.toBeNull();
|
||||
});
|
||||
|
||||
const Comp = () => {
|
||||
const [toggle, setToggle] = useState(true);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggle ? <Child /> : null}
|
||||
<button onClick={() => setToggle(false)}>Unmount</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Child = () => {
|
||||
onMounted(fn);
|
||||
return <span />;
|
||||
};
|
||||
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
render(<Comp />, container);
|
||||
|
||||
expect(document.querySelector('span')).not.toBeNull();
|
||||
|
||||
act(() => {
|
||||
container.querySelector('button').dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
});
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should call the onUnmounted after the component unmounts', () => {
|
||||
const fn = vi.fn(() => {
|
||||
// 断言在组件卸载之后,子组件不存在于 DOM 中
|
||||
expect(document.querySelector('span')).not.toBeNull();
|
||||
});
|
||||
|
||||
const Comp = () => {
|
||||
const [toggle, setToggle] = useState(true);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggle ? <Child /> : null}
|
||||
<button onClick={() => setToggle(false)}>Unmount</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Child = () => {
|
||||
onUnmounted(fn);
|
||||
return <span />;
|
||||
};
|
||||
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
render(<Comp />, container);
|
||||
|
||||
expect(document.querySelector('span')).not.toBeNull();
|
||||
|
||||
act(() => {
|
||||
container.querySelector('button').dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
});
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should call the onBeforeUnmount before the component unmounts', () => {
|
||||
const fn = vi.fn(() => {
|
||||
// 断言在组件卸载之前,子组件仍然存在于 DOM 中
|
||||
|
@ -56,4 +160,34 @@ describe('lifecycle', () => {
|
|||
|
||||
expect(document.querySelector('span')).toBeNull();
|
||||
});
|
||||
|
||||
it('should call the onUpdated/onBeforeUpdated', () => {
|
||||
const fn = vi.fn(() => {
|
||||
expect(document.querySelector('span').outerHTML).toBe('<span>0</span>');
|
||||
});
|
||||
|
||||
const Comp = () => {
|
||||
const [toggle, setToggle] = useState(true);
|
||||
|
||||
onUpdated(fn);
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>{toggle ? 1 : 0}</span>
|
||||
<button onClick={() => setToggle(false)}>Unmount</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
render(<Comp />, container);
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(0);
|
||||
expect(document.querySelector('span').outerHTML).toBe('<span>1</span>');
|
||||
|
||||
container.querySelector('button').dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
|
||||
expect(fn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"files": [
|
||||
"src/index.ts"
|
||||
],
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"declarationDir": "./build/@types"
|
||||
},
|
||||
}
|
|
@ -1,13 +1,35 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"outDir": "./build",
|
||||
"incremental": false,
|
||||
"sourceMap": true,
|
||||
"allowJs": true, // allowJs=true => tsc compile js as module, no type check
|
||||
"checkJs": false, // Disable ts error checking in js
|
||||
"strict": true, // js-ts mixed setting
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": false, // 等大部分js代码改成ts之后再启用.
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitThis": true,
|
||||
"module": "CommonJS",
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"moduleResolution": "node",
|
||||
"target": "es5",
|
||||
"jsx": "preserve",
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": true,
|
||||
"alwaysStrict": true,
|
||||
"esModuleInterop": true,
|
||||
"declaration": true,
|
||||
"experimentalDecorators": true,
|
||||
"downlevelIteration": true,
|
||||
"types": ["jest"], // 赋值为空数组使@types/node不会起作用
|
||||
"lib": ["dom", "esnext", "ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020"],
|
||||
"baseUrl": ".",
|
||||
"rootDir": "./src",
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"ts-node": {
|
||||
"esm": true
|
||||
}
|
||||
"exclude": ["node_modules", "**/*.spec.ts"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue