From a08ec49f12151b131ea486bd992d4e7da95a89aa Mon Sep 17 00:00:00 2001 From: Logic <376693576@qq.com> Date: Wed, 9 Oct 2019 15:02:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?ts=20=E6=9C=AA=E5=AE=8C=E5=BE=85=E7=BB=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 15 +++- src/global.d.ts | 1 + src/{index.js => index.tsx} | 4 +- src/models/{app.js => app.ts} | 0 src/root/{index.js => index.tsx} | 6 +- src/{serviceWorker.js => serviceWorker.ts} | 48 ++++++----- src/store/{index.js => index.ts} | 0 src/util/server.js | 20 ----- src/util/server.ts | 20 +++++ src/util/{tools.js => tools.ts} | 12 +-- tsconfig.json | 11 +++ webpack.dev.config.js | 92 ++++++++++++---------- webpack.production.config.js | 6 ++ 13 files changed, 138 insertions(+), 97 deletions(-) create mode 100644 src/global.d.ts rename src/{index.js => index.tsx} (86%) rename src/models/{app.js => app.ts} (100%) rename src/root/{index.js => index.tsx} (86%) rename src/{serviceWorker.js => serviceWorker.ts} (73%) rename src/store/{index.js => index.ts} (100%) delete mode 100644 src/util/server.js create mode 100644 src/util/server.ts rename src/util/{tools.js => tools.ts} (91%) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index e29e58d2..a9a23cec 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ }, "dependencies": { "@rematch/core": "^1.2.0", + "@types/axios": "^0.14.0", + "@types/react": "^16.9.5", + "@types/react-dom": "^16.9.1", "antd": "^3.23.6", "axios": "^0.19.0", "core-js": "^3.2.1", @@ -39,7 +42,7 @@ "redux": "^4.0.4" }, "devDependencies": { - "@babel/core": "^7.6.2", + "@babel/core": "^7.6.3", "@babel/plugin-proposal-class-properties": "^7.5.5", "@babel/plugin-proposal-decorators": "^7.6.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4", @@ -47,10 +50,12 @@ "@babel/plugin-proposal-optional-chaining": "^7.6.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-runtime": "^7.6.2", - "@babel/preset-env": "^7.6.2", - "@babel/preset-react": "^7.0.0", - "@babel/runtime": "^7.6.2", + "@babel/preset-env": "^7.6.3", + "@babel/preset-react": "^7.6.3", + "@babel/runtime": "^7.6.3", + "@types/react-redux": "^7.1.4", "autoprefixer": "^9.6.4", + "awesome-typescript-loader": "^5.2.1", "babel-eslint": "^10.0.3", "babel-loader": "^8.0.6", "babel-plugin-import": "^1.12.2", @@ -75,9 +80,11 @@ "optimize-css-assets-webpack-plugin": "^5.0.3", "postcss-loader": "^3.0.0", "prettier": "1.18.2", + "source-map-loader": "^0.2.4", "style-loader": "^1.0.0", "sw-precache-webpack-plugin": "^0.11.5", "terser-webpack-plugin": "^2.1.2", + "typescript": "^3.6.3", "url-loader": "^2.2.0", "webpack": "^4.41.0", "webpack-cli": "^3.3.9", diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 00000000..c20e0a53 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1 @@ +declare const axios: any; diff --git a/src/index.js b/src/index.tsx similarity index 86% rename from src/index.js rename to src/index.tsx index a1f8c309..cfd58156 100644 --- a/src/index.js +++ b/src/index.tsx @@ -15,6 +15,6 @@ ReactDOM.render(, document.getElementById("app-root")); serviceWorker.register(); -if (module.hot) { - module.hot.accept(); +if ((module as any).hot) { + (module as any).hot.accept(); } diff --git a/src/models/app.js b/src/models/app.ts similarity index 100% rename from src/models/app.js rename to src/models/app.ts diff --git a/src/root/index.js b/src/root/index.tsx similarity index 86% rename from src/root/index.js rename to src/root/index.tsx index 3ba9011c..05b31c51 100644 --- a/src/root/index.js +++ b/src/root/index.tsx @@ -10,10 +10,12 @@ import { Provider } from "react-redux"; import store from "../store"; import Routers from "../container/routers"; -export default function RootContainer() { +const RootContainer: React.FC = () => { return ( ); -} +}; + +export default RootContainer; diff --git a/src/serviceWorker.js b/src/serviceWorker.ts similarity index 73% rename from src/serviceWorker.js rename to src/serviceWorker.ts index 346afec3..15d90cb8 100644 --- a/src/serviceWorker.js +++ b/src/serviceWorker.ts @@ -8,22 +8,30 @@ // resources are updated in the background. // To learn more about the benefits of this model and instructions on how to -// opt-in, read http://bit.ly/CRA-PWA +// opt-in, read https://bit.ly/CRA-PWA const isLocalhost = Boolean( - window.location.hostname === "localhost" || + window.location.hostname === 'localhost' || // [::1] is the IPv6 localhost address. - window.location.hostname === "[::1]" || + window.location.hostname === '[::1]' || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ ) ); -export function register(config) { - if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + const publicUrl = new URL( + (process as { env: { [key: string]: string } }).env.PUBLIC_URL, + window.location.href + ); if (publicUrl.origin !== window.location.origin) { // Our service worker won't work if PUBLIC_URL is on a different origin // from what our page is served on. This might happen if a CDN is used to @@ -31,7 +39,7 @@ export function register(config) { return; } - window.addEventListener("load", () => { + window.addEventListener('load', () => { const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; if (isLocalhost) { @@ -42,8 +50,8 @@ export function register(config) { // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { console.log( - "This web app is being served cache-first by a service " + - "worker. To learn more, visit http://bit.ly/CRA-PWA" + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA' ); }); } else { @@ -54,7 +62,7 @@ export function register(config) { } } -function registerValidSW(swUrl, config) { +function registerValidSW(swUrl: string, config?: Config) { navigator.serviceWorker .register(swUrl) .then(registration => { @@ -64,14 +72,14 @@ function registerValidSW(swUrl, config) { return; } installingWorker.onstatechange = () => { - if (installingWorker.state === "installed") { + if (installingWorker.state === 'installed') { if (navigator.serviceWorker.controller) { // At this point, the updated precached content has been fetched, // but the previous service worker will still serve the older // content until all client tabs are closed. console.log( - "New content is available and will be used when all " + - "tabs for this page are closed. See http://bit.ly/CRA-PWA." + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' ); // Execute callback @@ -82,7 +90,7 @@ function registerValidSW(swUrl, config) { // At this point, everything has been precached. // It's the perfect time to display a // "Content is cached for offline use." message. - console.log("Content is cached for offline use."); + console.log('Content is cached for offline use.'); // Execute callback if (config && config.onSuccess) { @@ -94,19 +102,19 @@ function registerValidSW(swUrl, config) { }; }) .catch(error => { - console.error("Error during service worker registration:", error); + console.error('Error during service worker registration:', error); }); } -function checkValidServiceWorker(swUrl, config) { +function checkValidServiceWorker(swUrl: string, config?: Config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl) .then(response => { // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get("content-type"); + const contentType = response.headers.get('content-type'); if ( response.status === 404 || - (contentType != null && contentType.indexOf("javascript") === -1) + (contentType != null && contentType.indexOf('javascript') === -1) ) { // No service worker found. Probably a different app. Reload the page. navigator.serviceWorker.ready.then(registration => { @@ -121,13 +129,13 @@ function checkValidServiceWorker(swUrl, config) { }) .catch(() => { console.log( - "No internet connection found. App is running in offline mode." + 'No internet connection found. App is running in offline mode.' ); }); } export function unregister() { - if ("serviceWorker" in navigator) { + if ('serviceWorker' in navigator) { navigator.serviceWorker.ready.then(registration => { registration.unregister(); }); diff --git a/src/store/index.js b/src/store/index.ts similarity index 100% rename from src/store/index.js rename to src/store/index.ts diff --git a/src/util/server.js b/src/util/server.js deleted file mode 100644 index ff7892c1..00000000 --- a/src/util/server.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 自己封装的异步请求函数 - * APP中的所有请求都将汇聚于此 - * **/ - -import axios from "axios"; - -export default class ApiService { - static newServer(url, bodyObj = {}, type = "post") { - return axios({ - url, - method: type, - headers: { - "Content-Type": "application/json;charset=utf-8" - }, - withCredentials: true, - data: JSON.stringify(bodyObj) - }); - } -} diff --git a/src/util/server.ts b/src/util/server.ts new file mode 100644 index 00000000..7fe55ccc --- /dev/null +++ b/src/util/server.ts @@ -0,0 +1,20 @@ +/** + * 自己封装的异步请求函数 + * APP中的所有请求都将汇聚于此 + * **/ + +import axios, { Method } from "axios"; + +export default class ApiService { + static newServer(url: string, bodyObj: object = {}, method: Method = "post") { + return axios({ + url, + method, + headers: { + "Content-Type": "application/json;charset=utf-8", + }, + withCredentials: true, + data: JSON.stringify(bodyObj), + }); + } +} diff --git a/src/util/tools.js b/src/util/tools.ts similarity index 91% rename from src/util/tools.js rename to src/util/tools.ts index 9df7f61e..c964e7e8 100644 --- a/src/util/tools.js +++ b/src/util/tools.ts @@ -9,7 +9,7 @@ const tools = { str - 数字或字符串 x - 保留几位小数点 */ - pointX(str, x = 0) { + pointX(str: string | number, x: number = 0) { if (!str && str !== 0) { return str; } @@ -23,7 +23,7 @@ const tools = { /** 去掉字符串两端空格 */ - trim(str) { + trim(str: string) { const reg = /^\s*|\s*$/g; return str.replace(reg, ""); }, @@ -33,7 +33,7 @@ const tools = { 如:将123456转换为1****6,最多将字符串中间6个字符变成* 如果字符串长度小于等于2,将不会有效果 */ - addMosaic(str) { + addMosaic(str: string | number) { const s = String(str); const lenth = s.length; const howmuch = (() => { @@ -59,7 +59,7 @@ const tools = { 字符串加密 简单的加密方法 */ - compile(code) { + compile(code: string) { let c = String.fromCharCode(code.charCodeAt(0) + code.length); for (let i = 1; i < code.length; i++) { c += String.fromCharCode(code.charCodeAt(i) + code.charCodeAt(i - 1)); @@ -71,14 +71,14 @@ const tools = { 字符串解谜 对应上面的字符串加密方法 */ - uncompile(code) { + uncompile(code: string) { let c = String.fromCharCode(code.charCodeAt(0) - code.length); for (let i = 1; i < code.length; i++) { c += String.fromCharCode(code.charCodeAt(i) - c.charCodeAt(i - 1)); } console.log("解谜:", code, c); return c; - } + }, }; export default tools; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..4b18fd5f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "outDir": "./build/", + "sourceMap": true, + "noImplicitAny": true, + "module": "commonjs", + "target": "es5", + "jsx": "react" + }, + "include": ["./src/**/*"] +} diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 0cc913c0..b77f991f 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -1,28 +1,28 @@ /** 这是用于开发环境的webpack配置文件 **/ -const path = require('path'); // 获取绝对路径用 -const webpack = require('webpack'); // webpack核心 -const HtmlWebpackPlugin = require('html-webpack-plugin'); // 动态生成html插件 -const HappyPack = require('happypack'); // 多线程编译 -const FaviconsWebpackPlugin = require('favicons-webpack-plugin'); -const webpackbar = require('webpackbar'); -const PUBLIC_PATH = '/'; // 基础路径 +const path = require("path"); // 获取绝对路径用 +const webpack = require("webpack"); // webpack核心 +const HtmlWebpackPlugin = require("html-webpack-plugin"); // 动态生成html插件 +const HappyPack = require("happypack"); // 多线程编译 +const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); +const webpackbar = require("webpackbar"); +const PUBLIC_PATH = "/"; // 基础路径 module.exports = { - mode: 'development', + mode: "development", entry: [ - 'webpack-hot-middleware/client?reload=true&path=/__webpack_hmr', // webpack热更新插件,就这么写 - './src/index.js', // 项目入口 - './dll/vendor.dll.js', + "webpack-hot-middleware/client?reload=true&path=/__webpack_hmr", // webpack热更新插件,就这么写 + "./src/index.tsx", // 项目入口 + "./dll/vendor.dll.js", ], output: { - path: __dirname + '/', // 将打包好的文件放在此路径下,dev模式中,只会在内存中存在,不会真正的打包到此路径 + path: __dirname + "/", // 将打包好的文件放在此路径下,dev模式中,只会在内存中存在,不会真正的打包到此路径 publicPath: PUBLIC_PATH, // 文件解析路径,index.html中引用的路径会被设置为相对于此路径 - filename: 'bundle.js', // 编译后的文件名字 + filename: "bundle.js", // 编译后的文件名字 }, - devtool: 'eval-source-map', // 报错的时候在控制台输出哪一行报错 + devtool: "eval-source-map", // 报错的时候在控制台输出哪一行报错 optimization: { splitChunks: { - chunks: 'all', + chunks: "all", }, }, module: { @@ -30,35 +30,41 @@ module.exports = { { // 编译前通过eslint检查代码 (注释掉即可取消eslint检测) test: /\.js?$/, - enforce: 'pre', - use: ['eslint-loader'], - include: path.resolve(__dirname, 'src'), + enforce: "pre", + use: ["source-map-loader", "eslint-loader"], + include: path.resolve(__dirname, "src"), + }, + { + // .tsx 解析 + test: /\.tsx?$/, + use: ["awesome-typescript-loader"], + include: path.resolve(__dirname, "src"), }, { // .js .jsx用babel解析 test: /\.js?$/, - use: ['happypack/loader'], - include: path.resolve(__dirname, 'src'), + use: ["happypack/loader"], + include: path.resolve(__dirname, "src"), }, { // .css 解析 test: /\.css$/, - use: ['style-loader', 'css-loader', 'postcss-loader'], + use: ["style-loader", "css-loader", "postcss-loader"], }, { // .less 解析 test: /\.less$/, - use: ['style-loader', 'css-loader', 'postcss-loader', { loader: 'less-loader', options: { javascriptEnabled: true } }], + use: ["style-loader", "css-loader", "postcss-loader", { loader: "less-loader", options: { javascriptEnabled: true } }], }, { // 文件解析 test: /\.(eot|woff|otf|svg|ttf|woff2|appcache|mp3|mp4|pdf)(\?|$)/, - include: path.resolve(__dirname, 'src'), + include: path.resolve(__dirname, "src"), use: [ { - loader: 'file-loader', + loader: "file-loader", options: { - name: 'assets/[name].[hash:4].[ext]', + name: "assets/[name].[hash:4].[ext]", }, }, ], @@ -66,13 +72,13 @@ module.exports = { { // 图片解析 test: /\.(png|jpg|jpeg|gif)$/i, - include: path.resolve(__dirname, 'src'), + include: path.resolve(__dirname, "src"), use: [ { - loader: 'url-loader', + loader: "url-loader", options: { limit: 8192, - name: 'assets/[name].[hash:4].[ext]', + name: "assets/[name].[hash:4].[ext]", }, }, ], @@ -80,14 +86,14 @@ module.exports = { { // wasm文件解析 test: /\.wasm$/, - include: path.resolve(__dirname, 'src'), - type: 'webassembly/experimental', + include: path.resolve(__dirname, "src"), + type: "webassembly/experimental", }, { // xml文件解析 test: /\.xml$/, - include: path.resolve(__dirname, 'src'), - use: ['xml-loader'], + include: path.resolve(__dirname, "src"), + use: ["xml-loader"], }, ], }, @@ -95,7 +101,7 @@ module.exports = { new webpackbar(), new webpack.HotModuleReplacementPlugin(), // 热更新插件 new webpack.DefinePlugin({ - 'process.env': JSON.stringify({ + "process.env": JSON.stringify({ PUBLIC_URL: PUBLIC_PATH, }), }), @@ -105,26 +111,26 @@ module.exports = { 下面这个地址对应webpack.dll.config.js中生成的那个json文件的路径 这样webpack打包时,就先直接去这个json文件中把那些预编译的资源弄进来 **/ - manifest: require('./dll/vendor-manifest.json'), + manifest: require("./dll/vendor-manifest.json"), }), new HappyPack({ - loaders: ['babel-loader'], + loaders: ["babel-loader"], }), new HtmlWebpackPlugin({ // 根据模板插入css/js等生成最终HTML - filename: 'index.html', //生成的html存放路径,相对于 output.path - favicon: './public/favicon.png', // 自动把根目录下的favicon.ico图片加入html - template: './public/index.ejs', //html模板路径 + filename: "index.html", //生成的html存放路径,相对于 output.path + favicon: "./public/favicon.png", // 自动把根目录下的favicon.ico图片加入html + template: "./public/index.ejs", //html模板路径 inject: true, // 是否将js放在body的末尾 templateParameters: { dll: "", - manifest: '', + manifest: "", }, }), // 自动生成各种类型的favicon,这么做是为了以后各种设备上的扩展功能,比如PWA桌面图标 new FaviconsWebpackPlugin({ - logo: './public/favicon.png', - prefix: 'icons/', + logo: "./public/favicon.png", + prefix: "icons/", icons: { android: false, firefox: false, @@ -133,9 +139,9 @@ module.exports = { }), ], resolve: { - extensions: ['.js', '.jsx', '.less', '.css', '.wasm'], //后缀名自动补全 + extensions: [".js", ".jsx", ".less", ".css", ".wasm"], //后缀名自动补全 alias: { - '@': path.resolve(__dirname, 'src'), + "@": path.resolve(__dirname, "src"), }, }, }; diff --git a/webpack.production.config.js b/webpack.production.config.js index ed95cca8..17b6ddd2 100644 --- a/webpack.production.config.js +++ b/webpack.production.config.js @@ -53,6 +53,12 @@ module.exports = { }, module: { rules: [ + { + // .tsx 解析 + test: /\.tsx?$/, + use: ["awesome-typescript-loader"], + include: path.resolve(__dirname, "src"), + }, { // .js .jsx用babel解析 test: /\.js?$/, From dde1df46e4e4bff27f5767ec9067210dc2d3341a Mon Sep 17 00:00:00 2001 From: Logic <376693576@qq.com> Date: 2019年10月10日 10:54:49 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=BF=99ts=E7=9C=9F=E9=9A=BE=E9=85=8D?= =?UTF-8?q?=E5=95=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 5 +-- package.json | 2 + src/container/routers/{index.js => index.tsx} | 39 +++++++------------ src/global.d.ts | 1 - src/index.tsx | 4 +- src/models/app.ts | 21 ++++++---- src/models/{test.js => test.ts} | 27 +++++++------ src/root/index.tsx | 2 +- src/store/index.ts | 4 +- src/util/server.ts | 2 +- src/util/tools.ts | 20 ++++------ tsconfig.json | 4 +- webpack.dev.config.js | 10 ----- webpack.dll.config.js | 23 ----------- 14 files changed, 65 insertions(+), 99 deletions(-) rename src/container/routers/{index.js => index.tsx} (75%) rename src/models/{test.js => test.ts} (72%) delete mode 100644 webpack.dll.config.js diff --git a/.travis.yml b/.travis.yml index c4e153a9..72bfaf33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: node_js node_js: - - '10' - - '8' + - "10" + - "8" script: - - yarn dll - yarn build diff --git a/package.json b/package.json index a9a23cec..46ed4dae 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,8 @@ "@types/axios": "^0.14.0", "@types/react": "^16.9.5", "@types/react-dom": "^16.9.1", + "@types/react-loadable": "^5.5.1", + "@types/react-router-dom": "^5.1.0", "antd": "^3.23.6", "axios": "^0.19.0", "core-js": "^3.2.1", diff --git a/src/container/routers/index.js b/src/container/routers/index.tsx similarity index 75% rename from src/container/routers/index.js rename to src/container/routers/index.tsx index 2b8f173a..4fef928b 100644 --- a/src/container/routers/index.js +++ b/src/container/routers/index.tsx @@ -24,29 +24,30 @@ import "./index.less"; const Home = Loadable({ loader: () => import(/* webpackChunkName:'home' */ "../home"), loading: Loading, // 自定义的Loading动画组件 - timeout: 10000 // 可以设置一个超时时间(s)来应对网络慢的情况(在Loading动画组件中可以配置error信息) + timeout: 10000, // 可以设置一个超时时间(s)来应对网络慢的情况(在Loading动画组件中可以配置error信息) }); const Test = Loadable({ loader: () => import(/* webpackChunkName:'test' */ "../test"), - loading: Loading + loading: Loading, }); const TestClass = Loadable({ loader: () => import(/* webpackChunkName:'testclass' */ "../testclass"), - loading: Loading + loading: Loading, }); const Features = Loadable({ loader: () => import(/* webpackChunkName:'features' */ "../features"), - loading: Loading + loading: Loading, }); const NotFound = Loadable({ loader: () => import(/* webpackChunkName:'notfound' */ "../notfound"), - loading: Loading + loading: Loading, }); const history = createHistory(); // 实例化history对象 /** 组件 **/ -function RootRouterContainer(props) { +function RootRouterContainer(props: any) { + console.log("父级参数:", props); // 在组件加载完毕后触发 useEffect(() => { // 可以手动在此预加载指定的模块: @@ -57,7 +58,7 @@ function RootRouterContainer(props) { }, []); /** 简单权限控制 **/ - function onEnter(Component, props) { + function onEnter(Component: any, props: any) { // 例子:如果没有登录,直接跳转至login页 // if (sessionStorage.getItem('userInfo')) { // return ; @@ -77,22 +78,10 @@ function RootRouterContainer(props) {
- onEnter(Home, props)} - /> - onEnter(Features, props)} - /> - onEnter(Test, props)} - /> - onEnter(TestClass, props)} - /> + onEnter(Home, props)} /> + onEnter(Features, props)} /> + onEnter(Test, props)} /> + onEnter(TestClass, props)} /> @@ -110,6 +99,6 @@ function RootRouterContainer(props) { export default connect( state => ({}), dispatch => ({ - actions: {} - }) + actions: {}, + }), )(RootRouterContainer); diff --git a/src/global.d.ts b/src/global.d.ts index c20e0a53..e69de29b 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1 +0,0 @@ -declare const axios: any; diff --git a/src/index.tsx b/src/index.tsx index cfd58156..aeb0a5c3 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,8 +1,8 @@ /** APP入口 **/ import "core-js/stable"; import "regenerator-runtime/runtime"; -import React from "react"; -import ReactDOM from "react-dom"; +import * as React from "react"; +import * as ReactDOM from "react-dom"; import * as serviceWorker from "./serviceWorker"; import Root from "./root"; diff --git a/src/models/app.ts b/src/models/app.ts index 147b1eb3..b918f1c4 100644 --- a/src/models/app.ts +++ b/src/models/app.ts @@ -1,27 +1,34 @@ +import { prototype } from "stream"; + /** * 基本Model app.js, 在src/store/index.js中被挂载到store上,命名为app * 可用于存放通用信息,比如用户数据、角色、权限、省市区等通用数据 * **/ +interface IParams { + id?: string | number; + [propName: string]: any; +} + export default { /** store数据 **/ state: { - userinfo: null // 用户信息 + userinfo: null, // 用户信息 }, /** reducers **/ reducers: { - setUserInfo(state, payload) { + setUserInfo(state: object, payload: object) { return Object.assign({}, state, { - userinfo: payload + userinfo: payload, }); - } + }, }, /** actions 可以是一个对象,也可以是一个函数,函数的第1个参数自动被注入dispatch **/ effects: { // 模拟获取用户信息 - async getUserinfo(params = {}) { + async getUserinfo(params: IParams = {}) { const user = { id: params.id, username: "admin" }; this.setUserInfo(user); return user; - } - } + }, + }, }; diff --git a/src/models/test.js b/src/models/test.ts similarity index 72% rename from src/models/test.js rename to src/models/test.ts index 424c3a16..b6a14e4a 100644 --- a/src/models/test.js +++ b/src/models/test.ts @@ -6,34 +6,39 @@ import { message } from "antd"; import Server from "../util/server"; // 自己封装的异步请求方法 +interface IParams { + id?: string | number; + [propName: string]: any; +} + export default { /** store数据 **/ state: { count: 0, // 测试数字 - fetchvalue: [] // 异步请求的测试数据 + fetchvalue: [], // 异步请求的测试数据 }, /** reducers **/ reducers: { - setCount(state, payload) { + setCount(state: object, payload: number) { return Object.assign({}, state, { - count: payload + count: payload, }); }, - setFetchValue(state, payload) { + setFetchValue(state: object, payload: Array) { return Object.assign({}, state, { - fetchvalue: payload + fetchvalue: payload, }); - } + }, }, /** actions **/ - effects: dispatch => ({ + effects: (dispatch: Function) => ({ // 测试 - 数字加1 - onTestAdd(params) { + onTestAdd(params: number) { this.setCount(params + 1); // 这里会指向上面reducers中的setCount }, // 测试 - 异步请求 - async serverFetch(params = {}) { + async serverFetch(params: IParams = {}) { try { const res = await Server.newServer("url.ajax", params, "post"); if (res && res.data.status === 200) { @@ -43,6 +48,6 @@ export default { } catch (e) { message.error("网络错误", 1); } - } - }) + }, + }), }; diff --git a/src/root/index.tsx b/src/root/index.tsx index 05b31c51..7c9ce7d0 100644 --- a/src/root/index.tsx +++ b/src/root/index.tsx @@ -5,7 +5,7 @@ * */ /** 所需的各种插件 **/ -import React from "react"; +import * as React from "react"; import { Provider } from "react-redux"; import store from "../store"; import Routers from "../container/routers"; diff --git a/src/store/index.ts b/src/store/index.ts index 49e2c30b..16efc3f3 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,6 +7,6 @@ import test from "../models/test"; export default init({ models: { app, // 这里的命名很重要,即这个模块的名字 - test - } + test, + }, }); diff --git a/src/util/server.ts b/src/util/server.ts index 7fe55ccc..f6beeb7a 100644 --- a/src/util/server.ts +++ b/src/util/server.ts @@ -6,7 +6,7 @@ import axios, { Method } from "axios"; export default class ApiService { - static newServer(url: string, bodyObj: object = {}, method: Method = "post") { + static newServer(url: string, bodyObj: object = {}, method: Method = "post"): Promise { return axios({ url, method, diff --git a/src/util/tools.ts b/src/util/tools.ts index c964e7e8..438aae41 100644 --- a/src/util/tools.ts +++ b/src/util/tools.ts @@ -5,25 +5,21 @@ const tools = { 保留N位小数 最终返回的是字符串 若转换失败,返回参数原值 - @params - str - 数字或字符串 - x - 保留几位小数点 + @param str 字符串或数字 + @param x 保留几位小数 */ - pointX(str: string | number, x: number = 0) { - if (!str && str !== 0) { - return str; - } + pointX(str: string | number, x: number = 0): string { const temp = Number(str); if (temp === 0) { return temp.toFixed(x); } - return temp ? temp.toFixed(x) : str; + return temp ? temp.toFixed(x) : String(str); }, /** 去掉字符串两端空格 */ - trim(str: string) { + trim(str: string): string { const reg = /^\s*|\s*$/g; return str.replace(reg, ""); }, @@ -33,7 +29,7 @@ const tools = { 如:将123456转换为1****6,最多将字符串中间6个字符变成* 如果字符串长度小于等于2,将不会有效果 */ - addMosaic(str: string | number) { + addMosaic(str: string | number): string { const s = String(str); const lenth = s.length; const howmuch = (() => { @@ -59,7 +55,7 @@ const tools = { 字符串加密 简单的加密方法 */ - compile(code: string) { + compile(code: string): string { let c = String.fromCharCode(code.charCodeAt(0) + code.length); for (let i = 1; i < code.length; i++) { c += String.fromCharCode(code.charCodeAt(i) + code.charCodeAt(i - 1)); @@ -71,7 +67,7 @@ const tools = { 字符串解谜 对应上面的字符串加密方法 */ - uncompile(code: string) { + uncompile(code: string): string { let c = String.fromCharCode(code.charCodeAt(0) - code.length); for (let i = 1; i < code.length; i++) { c += String.fromCharCode(code.charCodeAt(i) - c.charCodeAt(i - 1)); diff --git a/tsconfig.json b/tsconfig.json index 4b18fd5f..e6a1a4c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,10 @@ "sourceMap": true, "noImplicitAny": true, "module": "commonjs", + "allowJs": true, "target": "es5", - "jsx": "react" + "jsx": "react", + "allowSyntheticDefaultImports": true }, "include": ["./src/**/*"] } diff --git a/webpack.dev.config.js b/webpack.dev.config.js index b77f991f..28b6579f 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -12,7 +12,6 @@ module.exports = { entry: [ "webpack-hot-middleware/client?reload=true&path=/__webpack_hmr", // webpack热更新插件,就这么写 "./src/index.tsx", // 项目入口 - "./dll/vendor.dll.js", ], output: { path: __dirname + "/", // 将打包好的文件放在此路径下,dev模式中,只会在内存中存在,不会真正的打包到此路径 @@ -105,14 +104,6 @@ module.exports = { PUBLIC_URL: PUBLIC_PATH, }), }), - new webpack.DllReferencePlugin({ - context: __dirname, - /** - 下面这个地址对应webpack.dll.config.js中生成的那个json文件的路径 - 这样webpack打包时,就先直接去这个json文件中把那些预编译的资源弄进来 - **/ - manifest: require("./dll/vendor-manifest.json"), - }), new HappyPack({ loaders: ["babel-loader"], }), @@ -123,7 +114,6 @@ module.exports = { template: "./public/index.ejs", //html模板路径 inject: true, // 是否将js放在body的末尾 templateParameters: { - dll: "", manifest: "", }, }), diff --git a/webpack.dll.config.js b/webpack.dll.config.js deleted file mode 100644 index f792a219..00000000 --- a/webpack.dll.config.js +++ /dev/null @@ -1,23 +0,0 @@ -const path = require('path'); -const webpack = require('webpack'); -const { dependencies } = require('./package.json'); -module.exports = { - mode: 'development', - entry: { - vendor: Object.keys(dependencies), - }, - output: { - path: path.join(__dirname, 'dll'), // 生成的dll.js路径,我是存在/build/dev中 - filename: '[name].dll.js', // 生成的文件名字 - library: '[name]_library', // 生成文件的一些映射关系,与下面DllPlugin中配置对应 - }, - plugins: [ - // 使用DllPlugin插件编译上面配置的NPM包 - new webpack.DllPlugin({ - // 会生成一个json文件,里面是关于dll.js的一些配置信息 - path: path.join(__dirname, 'dll', '[name]-manifest.json'), - name: '[name]_library', // 与上面output中配置对应 - context: __dirname, - }), - ], -};

AltStyle によって変換されたページ (->オリジナル) /