Skip to content

Commit

Permalink
feat: ykfe-utils ts化 (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangyuang committed Dec 13, 2019
1 parent 3ae4a6c commit e206978
Show file tree
Hide file tree
Showing 36 changed files with 309 additions and 96 deletions.
8 changes: 4 additions & 4 deletions .circleci/config.yml
Expand Up @@ -17,9 +17,8 @@ jobs:
- checkout
- restore_cache:
keys:
- v2-2-ssr-{{ .Branch }}-{{ checksum "package.json" }}
- v2-2-ssr-{{ .Branch }}-
- v2-2-ssr-
- v2-4.1-ssr-{{ .Branch }}-{{ checksum "package.json" }}
- v2-4.1-ssr
- run:
command: |
npm install --registry=https://registry.npm.taobao.org/
Expand All @@ -28,7 +27,8 @@ jobs:
paths:
- node_modules/
- ./packages/yk-cli/node_modules/
key: v2-2-ssr-{{ .Branch }}-{{ checksum "package.json" }}
- ./packages/ykfe-utils/node_modules/
key: v2-4.1-ssr-{{ .Branch }}-{{ checksum "package.json" }}
- persist_to_workspace:
root: ~/project
paths:
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
@@ -0,0 +1 @@
* linguist-language=TypeScript
4 changes: 2 additions & 2 deletions example/ssr-with-ts/package.json
@@ -1,6 +1,6 @@
{
"name": "ssr-with-ts",
"version": "2.0.10",
"version": "2.1.0",
"description": "ykfe",
"dependencies": {
"egg-scripts": "^2.10.0",
Expand All @@ -9,7 +9,7 @@
"react-dom": "^16.10.2",
"react-router-dom": "^5.1.2",
"yk-cli": "^2.6.0",
"ykfe-utils": "^2.1.2"
"ykfe-utils": "^2.6.0"
},
"devDependencies": {
"@babel/core": "^7.4.4",
Expand Down
10 changes: 6 additions & 4 deletions example/ssr-with-ts/src/app/controller/page.ts
@@ -1,8 +1,10 @@
import { controller, get, provide, inject, Context } from 'midway'
const renderToStream = require('ykfe-utils/lib/renderToStream')
const ssrConfig = require('../../../config/config.ssr')
import { Config } from 'ykfe-utils'
import renderToStream from 'ykfe-utils/lib/renderToStream'
import { IApiService } from '../../interface'

const ssrConfig: Config = require('../../../config/config.ssr')

@provide()
@controller('/')
export class Page {
Expand All @@ -19,8 +21,8 @@ export class Page {
this.ctx.type = 'text/html'
this.ctx.status = 200
this.ctx.apiService = this.service.index // 将service挂载到上下文对象
Object.assign(this.ctx.app.config, ssrConfig)
const stream = await renderToStream(this.ctx, this.ctx.app.config)
const config = Object.assign(this.ctx.app.config, ssrConfig)
const stream = await renderToStream(this.ctx, config)
this.ctx.res.write('<!DOCTYPE html>')
this.ctx.body = stream
} catch (error) {
Expand Down
8 changes: 4 additions & 4 deletions example/ssr-with-ts/web/entry.tsx
Expand Up @@ -2,11 +2,11 @@ import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, StaticRouter, Route, Switch } from 'react-router-dom'
import { Context } from 'midway'
import { getWrappedComponent, getComponent } from 'ykfe-utils'
import { RouteItem } from './interface/route'
import defaultLayout from './layout'

const { routes } = require('../config/config.ssr')
const { getWrappedComponent, getComponent } = require('ykfe-utils')

const clientRender = async (): Promise<void> => {
// 客户端渲染||hydrate
Expand All @@ -16,9 +16,9 @@ const clientRender = async (): Promise<void> => {
{
// 使用高阶组件getWrappedComponent使得csr首次进入页面以及csr/ssr切换路由时调用getInitialProps
routes.map((item: RouteItem) => {
const ActiveComponent = item.Component()
const Layout = ActiveComponent.Layout || defaultLayout
const WrappedComponent = getWrappedComponent(ActiveComponent)
const activeComponent = item.Component()
const Layout = activeComponent.Layout || defaultLayout
const WrappedComponent = getWrappedComponent(activeComponent)
return <Route exact={item.exact} key={item.path} path={item.path} render={() => {
return <Layout><WrappedComponent /></Layout>
}} />
Expand Down
10 changes: 3 additions & 7 deletions example/ssr-with-ts/web/interface/route.ts
@@ -1,9 +1,5 @@
export interface RouteItem {
path: string,
exact?: boolean,
Component (): Component
}
import { RouteItem } from 'ykfe-utils'

export interface RouteItem extends RouteItem {

export interface Component {
Layout?: new () => React.Component<object, object>
}
4 changes: 2 additions & 2 deletions example/ssr-with-ts/web/layout/index.tsx
Expand Up @@ -22,8 +22,8 @@ const Layout: SFC<LayoutProps> = (props: LayoutProps): JSX.Element | null => {
if (__isBrowser__) {
return commonNode(props)
} else {
const { serverData } = props.layoutData
const { injectCss, injectScript } = props.layoutData.app.config
const { serverData } = props.layoutData! // tslint:disable-line
const { injectCss, injectScript } = props.layoutData!.app.config // tslint:disable-line
return (
<html lang='en'>
<head>
Expand Down
5 changes: 4 additions & 1 deletion jest.config.js
@@ -1,5 +1,8 @@

module.exports = {
testEnvironment: 'node',
preset: 'ts-jest'
preset: 'ts-jest',
setupFilesAfterEnv: [
'<rootDir>/jest.setup.js'
]
}
4 changes: 4 additions & 0 deletions jest.setup.js
@@ -0,0 +1,4 @@
const React = require('react')
const { configure } = require('enzyme')
const Adapter = require('enzyme-adapter-react-16')
configure({ adapter: new Adapter() })
9 changes: 8 additions & 1 deletion package.json
Expand Up @@ -47,7 +47,8 @@
"**/es/",
"packages/ykfe-utils/src/loadable.js",
"**/node_modules/**",
"**/output/**"
"**/output/**",
"jest.setup.js"
],
"global": [
"__isBrowser__",
Expand All @@ -58,15 +59,21 @@
},
"homepage": "https://github.com/ykfe/egg-react-ssr#readme",
"devDependencies": {
"@types/enzyme": "^3.10.4",
"@types/jest": "^24.0.18",
"babel-eslint": "^10.0.2",
"chromedriver": "^79.0.0",
"codecov": "^3.5.0",
"egg": "^2.23.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.1",
"jest": "^24.9.0",
"lerna": "^3.8.0",
"nightwatch": "^1.2.1",
"pre-commit": "^1.2.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"standard": "^12.0.1",
"ts-jest": "^24.0.2",
"ts-node": "^8.5.4",
Expand Down
1 change: 0 additions & 1 deletion packages/yk-cli/package.json
Expand Up @@ -7,7 +7,6 @@
"sideEffects": false,
"scripts": {
"build": "rm -rf ./lib ./es && concurrently \"tsc -p ./tsconfig.cjs.json --sourceMap false\" \" tsc -p ./tsconfig.es6.json --sourceMap false\"",
"start": "node --inspect=19229 ./lib/index.js",
"dev": "concurrently \"tsc -w -p ./tsconfig.cjs.json \" \"tsc -w -p ./tsconfig.es6.json \""
},
"bin": {
Expand Down
4 changes: 3 additions & 1 deletion packages/yk-cli/src/interface/argv.ts
@@ -1,4 +1,6 @@
export interface Argv {
import yargs from 'yargs'

export interface Argv extends yargs.Arguments {
appName?: string
PORT?: Number
}
2 changes: 1 addition & 1 deletion packages/yk-cli/src/interface/option.ts
Expand Up @@ -9,7 +9,7 @@ export interface Optional {
tool?: string

/** 应用名称 */
appName?: string
appName: string

/** 样式预处理 */
style?: 'less' | 'sass' | 'css'
Expand Down
2 changes: 1 addition & 1 deletion packages/yk-cli/tests/check.test.ts
Expand Up @@ -7,7 +7,7 @@ jest.mock('inquirer', () => ({
delete: true
}))
}))
jest.spyOn(console, 'log')
console.log = jest.fn()

const inquirer = require('inquirer')
beforeAll(() => {
Expand Down
4 changes: 3 additions & 1 deletion packages/yk-cli/tests/update.test.ts
Expand Up @@ -8,10 +8,12 @@ jest.mock('../src/util/index', () => ({
resolveApp: jest.requireActual('../src/util').resolveApp
}))
jest.mock('ora')

console.log = jest.fn()

jest.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process exit')
})
jest.spyOn(console, 'log')

jest.mock('../package.json', () => ({ version: '1.0.0' }))

Expand Down
3 changes: 3 additions & 0 deletions packages/yk-cli/tests/util.test.ts
Expand Up @@ -21,6 +21,7 @@ describe('test getVersionEffective without cache', () => {
// 本地没有cache的情况应该返回false
test('no cahe can return false', async () => {
const data = await getVersionEffective({
appName: 'app',
language: 'javascript'
})
expect(data).toEqual(false)
Expand All @@ -37,6 +38,7 @@ describe('test getVersionEffective with cache', () => {
execSync(`echo '{"version":"1.0.0"}' > ${resolveApp(`./cache/example/ssr-with-js/package.json`)}`)
// 缓存过期应该返回false
const data = await getVersionEffective({
appName: 'app',
language: 'javascript'
})
expect(data).toEqual(false)
Expand All @@ -47,6 +49,7 @@ describe('test getVersionEffective with cache', () => {
const { 'dist-tags': { latest } } = await getWithPromise('https://registry.npm.taobao.org/ssr-with-js')
execSync(`echo '{"version": "${latest}"}' > ${resolveApp(`./cache/example/ssr-with-js/package.json`)}`)
const data = await getVersionEffective({
appName: 'app',
language: 'javascript'
})
expect(data).toEqual(true)
Expand Down
2 changes: 1 addition & 1 deletion packages/ykfe-utils/babel.config.js
@@ -1,9 +1,9 @@

module.exports = function (api) {
const isEs = process.env.BABEL_ENV === 'es'
api.cache(true)

const presets = [
'@babel/preset-typescript',
[
'@babel/preset-env',
{
Expand Down
21 changes: 14 additions & 7 deletions packages/ykfe-utils/package.json
@@ -1,27 +1,34 @@
{
"name": "ykfe-utils",
"version": "2.5.2",
"description": "",
"version": "2.6.0",
"description": "utils for ykfe",
"main": "lib/index.js",
"module": "es/index.js",
"sideEffects": false,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch:es": "NODE_ENV=production BABEL_ENV=es babel src --out-dir es --watch",
"watch:lib": "NODE_ENV=production BABEL_ENV=lib babel src --out-dir lib --watch",
"types": "concurrently \"tsc --outDir ./es\" \"tsc --outDir ./lib\" ",
"watch:es": "NODE_ENV=production BABEL_ENV=es babel src --out-dir es --watch --extensions '.ts,.tsx'",
"watch:lib": "NODE_ENV=production BABEL_ENV=lib babel src --out-dir lib --watch --extensions '.ts,.tsx'",
"watch": "concurrently \"npm run watch:es\" \"npm run watch:lib \""
},
"author": "",
"author": "zhangyuang",
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.4",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.7.4",
"@babel/runtime": "^7.5.5",
"@types/node": "^12.12.17",
"@types/react": "^16.9.15",
"@types/react-dom": "^16.9.4",
"@types/react-router-dom": "^5.1.3",
"babel-plugin-add-module-exports": "^1.0.2",
"concurrently": "^4.1.1"
"concurrently": "^4.1.1",
"midway": "^1.15.0",
"typescript": "^3.7.3"
},
"dependencies": {
"react": "^16.8.6",
Expand Down
@@ -1,33 +1,44 @@
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { FC } from '../interface/fc'

let _this = null
let _this: any = null
const popStateFn = () => {
// 使用popStateFn保存函数防止addEventListener重复注册
if (_this && _this.getInitialProps) {
_this.getInitialProps()
}
}

function GetInitialProps (WrappedComponent) {
class GetInitialPropsClass extends Component {
constructor (props) {
interface IProps {
history: {
action: string
}
}
interface IState {
getProps: boolean,
extraProps: Object
}

function GetInitialProps (WrappedComponent: FC) {
class GetInitialPropsClass extends Component<IProps, IState> {
constructor (props: IProps) {
super(props)
this.state = {
extraProps: {},
getProps: false
}
}

componentDidMount () {
async componentDidMount () {
const props = this.props
if (window.__USE_SSR__) {
_this = this // 修正_this指向,保证_this指向当前渲染的页面组件
window.addEventListener('popstate', popStateFn)
}
const getProps = !window.__USE_SSR__ || (props.history && props.history.action === 'PUSH')
if (getProps) {
this.getInitialProps()
await this.getInitialProps()
}
}

Expand Down
28 changes: 0 additions & 28 deletions packages/ykfe-utils/src/components/onlyCsr.js

This file was deleted.

0 comments on commit e206978

Please sign in to comment.