From 70ec5e7d4714435d5f29db112c6c4fa5c5dc1bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E4=BF=8A=E9=9B=84?= <15858209984@163.com> Date: Mon, 20 Aug 2018 21:15:05 +0800 Subject: [PATCH] =?UTF-8?q?typescript=20=E7=8E=AF=E5=A2=83=E6=90=AD?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .babelrc | 27 +++++++++++ README.md | 16 ++++++- package.json | 29 ++++++++++- src/app.styl | 6 +++ src/components/Hello.tsx | 31 ++++++++++-- src/components/interface.ts | 37 ++++++++++++++ src/components/type.ts | 59 +++++++++++++++++++++++ src/index.tsx | 27 +++++++++-- src/pages/home/home.md | 1 + src/pages/home/home.styl | 3 ++ src/pages/home/home.tsx | 17 +++++++ src/pages/home/index.ts | 3 ++ src/pages/leftNav/index.ts | 1 + src/pages/leftNav/leftNav.md | 1 + src/pages/leftNav/leftNav.styl | 3 ++ src/pages/leftNav/leftNav.tsx | 55 +++++++++++++++++++++ src/router.tsx | 53 ++++++++++++++++++++ src/util/index.ts | 3 -- tsconfig.json | 18 +++---- webpack.config.js | 88 ++++++++++++++++++++++++++++++++-- 20 files changed, 453 insertions(+), 25 deletions(-) create mode 100644 .babelrc create mode 100644 src/app.styl create mode 100644 src/components/interface.ts create mode 100644 src/components/type.ts create mode 100644 src/pages/home/home.md create mode 100644 src/pages/home/home.styl create mode 100644 src/pages/home/home.tsx create mode 100644 src/pages/home/index.ts create mode 100644 src/pages/leftNav/index.ts create mode 100644 src/pages/leftNav/leftNav.md create mode 100644 src/pages/leftNav/leftNav.styl create mode 100644 src/pages/leftNav/leftNav.tsx create mode 100644 src/router.tsx diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..9443ebe --- /dev/null +++ b/.babelrc @@ -0,0 +1,27 @@ + +{ + "presets": [ + [ + "env", + { + "targets": { + "browsers": [ + ">1%", + "last 3 versions" + ] + } + } + ], + "stage-2", + "latest", + "react" + ], + "plugins": [ + "syntax-dynamic-import", + "transform-class-properties", ["import", { + "libraryName": "antd", + "libraryDirectory": "es", + "style": true + }] + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 62d6715..c710e38 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# webpack4-es6-react-typescript +##### webpack4-es6-react-typescript + +##### 前言 +typescript 逐渐出现在大家的项目中,作为前端的一员,typescript还是需要学习的 +jest 一个好的项目应该是存在大量测试代码 + +##### 学习目的 +- typescript +- jest + + +##### 目前阶段 +- typescript 环境搭建 +- 搭建jest环境 +- 在typescript中使用jest测试 diff --git a/package.json b/package.json index d74da3a..d14f589 100644 --- a/package.json +++ b/package.json @@ -18,15 +18,40 @@ }, "homepage": "https://github.com/NewPrototype/webpack4-es6-react-typescript#readme", "dependencies": { - "@types/react": "^16.4.9", + "@types/react": "^16.4.11", "@types/react-dom": "^16.0.7", + "@types/react-loadable": "^5.4.1", + "@types/react-router-dom": "^4.3.0", + "antd": "^3.8.2", "react": "^16.4.2", - "react-dom": "^16.4.2" + "react-dom": "^16.4.2", + "react-loadable": "^5.5.0", + "react-router-dom": "^4.3.1" }, "devDependencies": { + "autoprefixer": "^9.1.2", "awesome-typescript-loader": "^5.2.0", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.5", + "babel-plugin-import": "^1.7.0", + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-preset-env": "^1.6.1", + "babel-preset-latest": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "css-loader": "^1.0.0", "html-webpack-plugin": "^3.2.0", + "import": "^0.0.6", + "less": "^3.8.1", + "less-loader": "^4.1.0", + "postcss-loader": "^3.0.0", "source-map-loader": "^0.2.3", + "style-loader": "^0.22.1", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "ts-import-plugin": "^1.5.4", + "ts-loader": "^4.5.0", "typescript": "^3.0.1", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", diff --git a/src/app.styl b/src/app.styl new file mode 100644 index 0000000..04fcc6d --- /dev/null +++ b/src/app.styl @@ -0,0 +1,6 @@ + +// @import '~antd/dist/antd.css'; + +.main{ + display: flex; +} \ No newline at end of file diff --git a/src/components/Hello.tsx b/src/components/Hello.tsx index 0a9b4a1..45896d2 100644 --- a/src/components/Hello.tsx +++ b/src/components/Hello.tsx @@ -1,7 +1,32 @@ import * as React from 'react'; -export interface HelloProps { compiler: string; framework: string; }; +interface HelloProps { compiler: string; framework: string; }; + + + + +class Student { + fullName: string; + constructor(public firstName: string, public middleInitial: string, public lastName: string) { + this.fullName = `${firstName}${middleInitial}${lastName}` + } +} + + +interface Person { + firstName: string; + lastName: string; +} + +function greeter(person: Person):string { + return `hello, ${person.firstName} ${person.lastName}` +} +let user = new Student('Jane', "M", "user"); +console.log(greeter(user)) export const Hello = (props: HelloProps) => ( -

{props.framework} {props.compiler}

-) \ No newline at end of file +

{props.framework} {props.compiler} {greeter(user)}

+) + + + diff --git a/src/components/interface.ts b/src/components/interface.ts new file mode 100644 index 0000000..6916691 --- /dev/null +++ b/src/components/interface.ts @@ -0,0 +1,37 @@ + +/**接口 interface */ + + +function printLabel(labelObj:{label:string}){ + console.log(labelObj.label) +} + +printLabel({label:'hi'}) + + + + + +interface LabelValue{ + label:string, + value?:string //可选 + +} + +function printLabelInter(labelItem:LabelValue):{label:string}{ + console.log(labelItem.label) + return labelItem +} +printLabelInter({label:'hello'}) + + +interface Point { + readonly x:number; //只读 +} + +let p:Point={x:10}; +// p.x=1200 //只读 + + + +export default 'interface'; \ No newline at end of file diff --git a/src/components/type.ts b/src/components/type.ts new file mode 100644 index 0000000..567428b --- /dev/null +++ b/src/components/type.ts @@ -0,0 +1,59 @@ + +/**基础类型 */ +let isDone:boolean=false; + +let decLiteral:number=123; + +let name:string='bob'; + +let list:number[]=[1,2,3,4] +let list2:Array=[12,3,45,] +let list3:any[]=[1,2,false]; +let list4:Array=[12,'str'] + +let arr:[string,number] + +arr=['hello',123] +arr[3]=1; + +//枚举 如果没有默认值获取的下标 +enum Color {Red,Green=3,Blue} +//可以设置默认值 + +let c:string=Color[3]; +console.log(c,'--') + +let notSure:any=4; +notSure='hi'; + +let prettySure:object={}; + + +function warnUser():string{ + return 'hi' +} +/** + * + *void表示没有任何返回值 + */ +function number():void{ + console.log('---12') +} + +/** + *never类型表示的是那些永不存在的值的类型 + * + * @returns {never} + */ +function error():never{ + throw new Error('错误') +} + +//断言 程序员自己来检测 + +let someValue:string='this is a string'; +let strLength =(someValue).length; +let strLength1 =(someValue as string).length; + +export default isDone + diff --git a/src/index.tsx b/src/index.tsx index 3073730..73ebe96 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,19 +1,36 @@ import * as React from 'react'; import * as ReactDom from 'react-dom'; -import { Hello } from './components/Hello'; +import {HashRouter} from 'react-router-dom'; -import { aa } from './util/index' -console.log(aa) -console.log(module,'--') + +import Router from './router' +import LeftNav from 'pages/leftNav' + +import './app.styl' + +declare let module: any; + if (module.hot) { module.hot.accept(); } +class App extends React.Component { + render() { + return
+ + +
+ } +} + + ReactDom.render( - , + + + , document.getElementById('example') ); diff --git a/src/pages/home/home.md b/src/pages/home/home.md new file mode 100644 index 0000000..30ed8d9 --- /dev/null +++ b/src/pages/home/home.md @@ -0,0 +1 @@ +### home diff --git a/src/pages/home/home.styl b/src/pages/home/home.styl new file mode 100644 index 0000000..9161a1f --- /dev/null +++ b/src/pages/home/home.styl @@ -0,0 +1,3 @@ +.home{ + +} \ No newline at end of file diff --git a/src/pages/home/home.tsx b/src/pages/home/home.tsx new file mode 100644 index 0000000..cba3db3 --- /dev/null +++ b/src/pages/home/home.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; + +import { Avatar } from 'antd'; + + +import './home.styl' + + +export default class home extends React.Component { + render() { + return ( +
+ home +
+ ); + } +} diff --git a/src/pages/home/index.ts b/src/pages/home/index.ts new file mode 100644 index 0000000..35dab3c --- /dev/null +++ b/src/pages/home/index.ts @@ -0,0 +1,3 @@ +import Home from './home'; + +export default Home; diff --git a/src/pages/leftNav/index.ts b/src/pages/leftNav/index.ts new file mode 100644 index 0000000..8889dc0 --- /dev/null +++ b/src/pages/leftNav/index.ts @@ -0,0 +1 @@ +export { default } from "./leftNav"; \ No newline at end of file diff --git a/src/pages/leftNav/leftNav.md b/src/pages/leftNav/leftNav.md new file mode 100644 index 0000000..7c9c1f1 --- /dev/null +++ b/src/pages/leftNav/leftNav.md @@ -0,0 +1 @@ +### leftNav diff --git a/src/pages/leftNav/leftNav.styl b/src/pages/leftNav/leftNav.styl new file mode 100644 index 0000000..6df1c56 --- /dev/null +++ b/src/pages/leftNav/leftNav.styl @@ -0,0 +1,3 @@ +.leftNav{ + +} \ No newline at end of file diff --git a/src/pages/leftNav/leftNav.tsx b/src/pages/leftNav/leftNav.tsx new file mode 100644 index 0000000..8244abf --- /dev/null +++ b/src/pages/leftNav/leftNav.tsx @@ -0,0 +1,55 @@ +import * as React from 'react'; +import './leftNav.styl'; + +import { Menu, Icon } from 'antd'; + +import { withRouter } from 'react-router-dom'; + +interface LeftNavProps { + history: any, +} + + +let router: object[] = [ + { key: '/', text: '首页1', icon: 'pie-chart' }, + { key: '/home2', text: '首页2', icon: 'mail' }, +] + +export default withRouter( + class LeftNav extends React.Component { + constructor(props: LeftNavProps) { + super(props) + this.state = { + openKeys: ['sub1'], + }; + } + onSelect = (e: {key:string}) => { + this.props.history.push(e.key) + }; + render() { + return ( + + { + router.map((value: { key: string, icon: string, text: string }, index) => { + return + + {value.text} + + }) + } + + + ); + } + } +) + + + + + diff --git a/src/router.tsx b/src/router.tsx new file mode 100644 index 0000000..9384cf1 --- /dev/null +++ b/src/router.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; + +import { Switch, Route } from 'react-router-dom'; + +import Loadable from 'react-loadable'; + + + + + + +const Loading = (props: any) => { + if (props.error) { + return
Error!
; + } else if (props.timedOut) { + return
Taking a long time...
; + } else if (props.pastDelay) { + return
Loading...
; + } else { + return null; + } +} + +const loadableOption = { + delay: 300, + timeout: 1000, + loading: Loading, +} + +const routers = [ + { + path: '/', + exact: true, + component: Loadable({ + loader: () => import('./pages/home/index'), + loading: Loading, + }) + } +] + + +const Routers = () => ( + + { + routers.map(({ component, path, exact }, index) => { + return + }) + } + +); + + +export default Routers \ No newline at end of file diff --git a/src/util/index.ts b/src/util/index.ts index 17bad41..e69de29 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,3 +0,0 @@ -export const aa=()=>{ - return 123 -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5ec12dd..1bf6d63 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,15 @@ { "compilerOptions": { - "outDir": "./dist/", - "sourceMap": true, - "noImplicitAny": true, - "module": "commonjs", - "target": "es5", - "jsx": "react" + "outDir": "./dist/", + "sourceMap": true, + "noImplicitAny": true, + "module": "commonjs", + "target": "es5", + "jsx": "react", + "lib": ["es2015", "dom","es2015","ES2018"], + "experimentalDecorators": true }, "include": [ - "./src/**/*" - ] + "./src/**/*" + ], } diff --git a/webpack.config.js b/webpack.config.js index b22b093..a975f63 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,7 @@ const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); //html +const tsImportPluginFactory = require('ts-import-plugin') + module.exports = { entry: './src/index.tsx', devServer: { @@ -15,16 +17,96 @@ module.exports = { // Enable sourcemaps for debugging webpack's output. devtool: 'source-map', - resolve: { // Add '.ts' and '.tsx' as resolvable extensions. extensions: ['.ts', '.tsx', '.js', '.json'], + alias: { + "pages": path.resolve(__dirname, 'src/pages'), + } }, - module: { rules: [ + { + test: /\.less/, + use: [ + { loader: 'style-loader' }, + { + loader: 'css-loader', + }, + { + loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: (loader) => [ + require('autoprefixer')(), + ] + } + }, + { loader: 'less-loader' ,options:{javascriptEnabled:true}}, + ], + }, // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. - { test: /\.tsx?$/, loader: 'awesome-typescript-loader' }, + { + test: /\.(ts||tsx)?$/, use: [ + { + loader: 'babel-loader' + }, + { + loader: 'ts-loader', + options: { + transpileOnly: true, + getCustomTransformers: () => ({ + before: [ tsImportPluginFactory({ + libraryName: 'antd', + libraryDirectory: 'es', + style: true, + }) ] + }), + compilerOptions: { + module: 'es2015' + } + }, + } + ] + }, + { + test: /\.css$/, + // exclude: /(node_modules|bower_components)/, + // include: [path.resolve(__dirname, 'src')], + use: [ + { + loader: 'css-loader', + }, + { + loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: (loader) => [ + require('autoprefixer')(), + ] + } + }, + ], + }, + + { + test: /\.styl/, + exclude: /(node_modules|bower_components)/, + include: [path.resolve(__dirname, 'src')], + use: [ + { loader: 'style-loader' }, + { + loader: 'css-loader', + }, + { + loader: 'postcss-loader', options: { + ident: 'postcss', + plugins: (loader) => [ + require('autoprefixer')(), + ] + } + }, + { loader: 'stylus-loader' }, + ], + }, // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. { enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' },