Skip to content

Commit

Permalink
release(rax): v1.2.1
Browse files Browse the repository at this point in the history
release v1.2.1
  • Loading branch information
imsobear committed Sep 1, 2021
2 parents 8a4f1b0 + 9391d7a commit aef8c54
Show file tree
Hide file tree
Showing 23 changed files with 315 additions and 174 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/auto-publisher.yml
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm run setup
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bench.yml
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- master
pull_request:
brenches:
branches:
- '^bench'

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x]
node-version: [12.x]
steps:
- uses: actions/checkout@v2
- name: Set branch name
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -12,3 +12,4 @@ coverage/
node_modules/
examples/test
.eslintcache
*.lock
14 changes: 12 additions & 2 deletions babel.config.js
Expand Up @@ -17,9 +17,19 @@ module.exports = function(api) {
],
'plugins': [
'@babel/plugin-proposal-export-default-from',
['@babel/plugin-proposal-class-properties', { 'loose': false }],
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
],
'babel-plugin-transform-jsx-stylesheet',
['@babel/plugin-proposal-decorators', { 'legacy': true }],
[
'@babel/plugin-proposal-decorators',
{
decoratorsBeforeExport: true
}
],
'@babel/plugin-syntax-dynamic-import',
],
'ignore': [
Expand Down
25 changes: 10 additions & 15 deletions lerna.json
@@ -1,20 +1,15 @@
{
"version": "1.0.0",
"packages": [
"packages/*"
],
"version": "1.7.0",
"npmClient": "ayarn",
"useWorkspaces": true,
"command": {
"bootstrap": {
"npmClientArgs": [
"--no-package-lock"
]
},
"publish": {
"skipGit": true,
"allowBranch": "master",
"ignoreChanges": [
"*.md"
]
"npmClientArgs": ["--no-lockfile"]
}
}
},
"packages": [
"packages/*",
"scripts/bench"
]
}

35 changes: 14 additions & 21 deletions package.json
@@ -1,9 +1,5 @@
{
"private": true,
"devEngines": {
"node": "8.x || 9.x || 10.x || 11.x",
"npm": "6.x"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/plugin-proposal-class-properties": "^7.2.0",
Expand All @@ -15,13 +11,12 @@
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@rollup/plugin-babel": "^5.2.1",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@rollup/plugin-replace": "^2.3.4",
"@rollup/plugin-virtual": "^2.0.3",
"@typescript-eslint/eslint-plugin": "^4.8.2",
"@typescript-eslint/parser": "^4.8.2",
"axios": "^0.21.0",
"axios": "^0.21.1",
"babel-eslint": "^10.0.3",
"babel-jest": "^26.6.3",
"babel-loader": "^8.0.4",
Expand All @@ -36,12 +31,11 @@
"eslint-config-rax": "^0.1.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-module": "^0.1.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react": "7.24.0",
"findup": "^0.1.5",
"ghooks": "^2.0.4",
"glob": "^7.1.3",
"gzip-size": "^5.0.0",
"image-source-loader": "^0.6.5",
"istanbul-api": "^2.0.6",
"istanbul-lib-coverage": "^2.0.1",
"jest": "^26.6.3",
Expand All @@ -51,21 +45,16 @@
"lerna": "^3.16.4",
"minimatch": "^3.0.4",
"minimist": "^1.2.0",
"rax-webpack-plugin": "^0.6.5",
"rimraf": "^2.6.2",
"rollup": "^2.33.3",
"rollup-plugin-terser": "^7.0.2",
"semver": "^7.1.0",
"semver-regex": "^2.0.0",
"stylesheet-loader": "^0.6.5",
"terser-webpack-plugin": "^5.0.3",
"typescript": "^3.7.5",
"typescript": "^4.0.0",
"uppercamelcase": "^3.0.0",
"webpack": "^4.27.1"
},
"scripts": {
"bootstrap": "npm run clean && lerna bootstrap --no-ci && npm run build",
"setup": "rm -rf node_modules && npm install --registry=https://registry.npm.taobao.org/ && npm run bootstrap",
"setup": "rm -rf node_modules && yarn install && npm run clean && npm run build",
"build:compile": "npm run clean:compile && npm run build:compile:packages",
"build:compile:packages": "node ./scripts/compile-packages.js",
"build:dist": "npm run clean:dist && node ./scripts/dist-core.js",
Expand All @@ -77,9 +66,8 @@
"lint:fix": "eslint --cache --ext .js,.jsx --fix ./",
"coverage": "npm run test -- --coverage",
"coverage:upload": "npm run clean:coverage && npm run coverage && node ./scripts/mapCoverage.js && codecov",
"publish": "node ./scripts/publish.js",
"clean:dist": "rm -rf ./packages/*/dist",
"clean:compile": "rm -rf ./packages/*/lib",
"clean:compile": "rm -rf ./packages/*/lib && rm -rf ./packages/*/es",
"clean:coverage": "rm -rf ./coverage",
"clean:modules": "rm -rf ./packages/*/node_modules",
"clean": "jest --clearCache && lerna clean --yes && npm run clean:modules && npm run clean:compile && npm run clean:dist && npm run clean:coverage",
Expand All @@ -89,10 +77,15 @@
},
"config": {
"ghooks": {
"commit-msg": "./scripts/validate-commit-msg.js"
"commit-msg": "./scripts/validate-commit-msg.js",
"pre-commit": "npm run lint"
},
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
},
"workspaces": [
"packages/*",
"scripts/*"
]
}
7 changes: 7 additions & 0 deletions packages/rax/CHANGELOG.md
@@ -0,0 +1,7 @@
## CHANGELOG

### 1.2.1

- refactor: change output result format, avoid mixing `IIFE` and `CJS`
- chore: avoid throw error when update unmounted component
- fix: add error message to `getDerivedStateFromError` hook
2 changes: 1 addition & 1 deletion packages/rax/index.js
@@ -1,5 +1,5 @@
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/rax.min.js');
} else {
module.exports = require('./lib/index.js');
module.exports = require('./dist/rax.js');
}
2 changes: 1 addition & 1 deletion packages/rax/package.json
@@ -1,6 +1,6 @@
{
"name": "rax",
"version": "1.2.0",
"version": "1.2.1",
"description": "A universal React-compatible render engine.",
"license": "BSD-3-Clause",
"main": "index.js",
Expand Down
115 changes: 115 additions & 0 deletions packages/rax/src/__tests__/asyncUpdate.js
@@ -0,0 +1,115 @@
/* @jsx createElement */

import createElement from '../createElement';
import Component from '../vdom/component';
import render from '../render';
import Host from '../vdom/host';
import ServerDriver from 'driver-server';
import { useState, useEffect } from '../hooks';

describe('update unmounted component', () => {
function createNodeElement(tagName) {
return {
nodeType: 1,
tagName: tagName.toUpperCase(),
attributes: {},
style: {},
childNodes: [],
parentNode: null
};
}

beforeEach(function() {
Host.driver = ServerDriver;
jest.useFakeTimers();
});

afterEach(function() {
Host.driver = null;
jest.useRealTimers();
});

it('should warn about class component', () => {
const container = createNodeElement('div');
let destroyChild;

class Child extends Component {
state = {
name: 'hello'
}
componentDidMount() {
setTimeout(() => {
this.setState({
name: 'work'
});
}, 1000);
}
render() {
return <div>{this.state.name}</div>;
}
}

class App extends Component {
state = {
showChild: true
}
componentDidMount() {
destroyChild = () => {
this.setState({
showChild: false
});
};
}
render() {
return (<div>
{ this.state.showChild ? <Child /> : null }
</div>);
}
}

expect(() => {
render(<App />, container);
destroyChild();
jest.runAllTimers();
}).toWarnDev("Warning: Can't perform a Rax state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.", { withoutStack: true });
});

it('should warn about function component', () => {
const container = createNodeElement('div');
let destroyChild;

function Child() {
const [name, setName] = useState('hello');
useEffect(() => {
setTimeout(() => {
setName('world');
}, 1000);
}, []);
return <div>{name}</div>;
}

class App extends Component {
state = {
showChild: true
}
componentDidMount() {
destroyChild = () => {
this.setState({
showChild: false
});
};
}
render() {
return (<div>
{ this.state.showChild ? <Child /> : null }
</div>);
}
}

expect(() => {
render(<App />, container);
destroyChild();
jest.runAllTimers();
}).toWarnDev("Warning: Can't perform a Rax state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.", { withoutStack: true });
});
});
2 changes: 1 addition & 1 deletion packages/rax/src/__tests__/createContext.js
Expand Up @@ -7,7 +7,7 @@ import render from '../render';
import ServerDriver from 'driver-server';
import createContext from '../createContext';
import createRef from '../createRef';
import {useState} from '../hooks';
import { useState } from '../hooks';

describe('createContext', () => {
function createNodeElement(tagName) {
Expand Down
4 changes: 3 additions & 1 deletion packages/rax/src/compat/index.js
@@ -1,9 +1,11 @@
import * as Rax from '../../index';
import * as RaxCore from '../../index';
import Children from 'rax-children';
import isValidElement from 'rax-is-valid-element';
import createFactory from 'rax-create-factory';
import cloneElement from 'rax-clone-element';

const Rax = RaxCore;

Rax.Children = Children;
Rax.isValidElement = isValidElement;
Rax.createFactory = createFactory;
Expand Down
40 changes: 40 additions & 0 deletions packages/rax/src/vdom/__tests__/composite.js
Expand Up @@ -762,6 +762,46 @@ describe('CompositeComponent', function() {
expect(container.childNodes[0].childNodes[0].data).toBe('Something went wrong.');
});

it('should catch the exact error with getDerivedStateFromError.', () => {
let caughtError;
let exampleError = new Error('Example error message');
let container = createNodeElement('div');

class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}

static getDerivedStateFromError(error) {
caughtError = error;
return { hasError: true, error };
}

render() {
if (this.state.hasError) {
return <h1>{this.state.error.message}</h1>;
}

return this.props.children;
}
}

function BrokenRender(props) {
throw exampleError;
}

render(
<ErrorBoundary>
<BrokenRender />
</ErrorBoundary>, container);

jest.runAllTimers();

expect(caughtError).toBe(exampleError);
expect(container.childNodes[0].childNodes[0].data).toBe('Example error message');
});

it('should render correct when prevRenderedComponent did not generate nodes', () => {
let container = createNodeElement('div');
class Frag extends Component {
Expand Down
2 changes: 1 addition & 1 deletion packages/rax/src/vdom/performInSandbox.js
Expand Up @@ -39,7 +39,7 @@ export function handleError(instance, error) {

// Update state to the next render to show the fallback UI.
if (boundary.constructor && boundary.constructor.getDerivedStateFromError) {
const state = boundary.constructor.getDerivedStateFromError();
const state = boundary.constructor.getDerivedStateFromError(error);
boundary.setState(state);
}
}, boundaryInternal.__parentInstance);
Expand Down

0 comments on commit aef8c54

Please sign in to comment.