Johnhong9527 5 years ago
parent
commit
5f9272620f
6 changed files with 143 additions and 70 deletions
  1. 59 25
      config/webpack.common.config.js
  2. 43 40
      config/webpack.prod.config.js
  3. 8 1
      package.json
  4. 0 0
      src/app.tsx
  5. 4 4
      src/index.js
  6. 29 0
      tsconfig.json

+ 59 - 25
config/webpack.common.config.js

@@ -1,51 +1,85 @@
-const path = require('path');
+const path = require("path");
+const resolve = dir => {
+  return path.resolve(process.cwd(), dir);
+};
 
 module.exports = {
   entry: {
-    index: './src/index.js',
-    framework: ['react', 'react-dom'],
+    index: "./src/index.js",
+    framework: ["react", "react-dom"]
   },
   output: {
-    filename: 'js/bundle.js',
-    path: path.resolve(__dirname, '../dist'),
+    path: path.resolve(__dirname, "../dist"),
+    sourceMapFilename: "[name].map",
+    chunkFilename: "static/js/[name].[chunkhash:8].js",
+    filename: "static/js/[name].[hash:8].js"
   },
 
   module: {
     rules: [
       {
-        test: /\.(js|jsx)$/,
-        use: 'babel-loader',
+        test: /\.(j|t)sx?$/,
+        include: [resolve("src")],
         exclude: /node_modules/,
+        loader: "babel-loader",
+        options: {
+          presets: [
+            [
+              "@babel/preset-env",
+              {
+                targets: { ie: 9 },
+                ignoreBrowserslistConfig: true,
+                useBuiltIns: false,
+                modules: false,
+                exclude: ["transform-typeof-symbol"]
+              }
+            ],
+            [
+              "@babel/preset-react",
+              {
+                targets: "last 2 versions, ie 11",
+                modules: false
+              }
+            ],
+            ["@babel/preset-typescript"]
+          ],
+          plugins: [
+            ["@babel/plugin-syntax-dynamic-import"],
+            ["@babel/plugin-proposal-decorators", { legacy: true }],
+            ["@babel/plugin-proposal-class-properties", { loose: true }]
+          ],
+          sourceMap: true
+        }
       },
       {
         test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
         use: [
           {
-            loader: 'url-loader',
+            loader: "url-loader",
             options: {
-              name: '[name].[ext]',
-              outputPath: 'images/',
+              name: "[name].[ext]",
+              outputPath: "images/",
               limit: 4096,
               fallback: {
-                loader: 'file-loader',
+                loader: "file-loader",
                 options: {
-                  name: 'img/[name].[hash:8].[ext]',
-                },
-              },
-            },
-          },
-        ],
+                  name: "img/[name].[hash:8].[ext]"
+                }
+              }
+            }
+          }
+        ]
       },
       {
         test: /\.(eot|ttf|svg|woff|woff2)$/,
         use: {
-          loader: 'file-loader',
+          loader: "file-loader",
           options: {
-            name: '[name]_[hash].[ext]',
-            outputPath: 'font/',
-          },
-        },
-      },
-    ],
-  },
+            name: "[name]_[hash].[ext]",
+            outputPath: "font/"
+          }
+        }
+      }
+    ]
+  }
 };

+ 43 - 40
config/webpack.prod.config.js

@@ -1,32 +1,35 @@
-const merge = require('webpack-merge');
-const common = require('./webpack.common.config.js');
+/*
+ * @Author: Johnhong9527
+ * @Date:   2020-05-12 16:35:36
+ * @Last Modified by:   Johnhong9527
+ * @Last Modified time: 2020-05-12 16:35:44
+ */
+const merge = require("webpack-merge");
+const common = require("./webpack.common.config.js");
 
-const HtmlWebpackPlugin = require('html-webpack-plugin');
-const { CleanWebpackPlugin } = require('clean-webpack-plugin');
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const MiniCssExtractPlugin = require('mini-css-extract-plugin');
-const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+const { CleanWebpackPlugin } = require("clean-webpack-plugin");
+const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
 
 module.exports = merge(common, {
-  mode: 'production',
-  output: {
-    filename: 'js/[name].[chunkhash:8].bundle.js',
-  },
+  mode: "production",
   module: {
     rules: [
       {
         test: /\.css$/,
-        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
+        use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
       },
       {
         test: /\.less$/,
         use: [
           MiniCssExtractPlugin.loader,
-          'css-loader',
-          'less-loader',
-          'postcss-loader',
-        ],
-      },
+          "css-loader",
+          "less-loader",
+          "postcss-loader"
+        ]
+      }
       // {
       //   test: /\.(scss|sass)$/,
       //   use: [
@@ -36,54 +39,54 @@ module.exports = merge(common, {
       //     'sass-loader'
       //   ]
       // },
-    ],
+    ]
   },
   plugins: [
     new HtmlWebpackPlugin({
-      filename: 'index.html',
-      template: 'public/index.html',
-      inject: 'body',
+      filename: "index.html",
+      template: "public/index.html",
+      inject: "body",
       minify: {
         removeComments: true,
-        collapseWhitespace: true,
-      },
+        collapseWhitespace: true
+      }
     }),
     new CleanWebpackPlugin(),
     new MiniCssExtractPlugin({
-      filename: 'css/[name].[hash].css',
-      chunkFilename: 'css/[id].[hash].css',
-    }),
+      filename: "css/[name].[hash].css",
+      chunkFilename: "css/[id].[hash].css"
+    })
   ],
   optimization: {
     minimizer: [
       new UglifyJsPlugin(),
       new OptimizeCssAssetsPlugin({
         assetNameRegExp: /\.css$/g,
-        cssProcessor: require('cssnano'),
+        cssProcessor: require("cssnano"),
         cssProcessorPluginOptions: {
-          preset: ['default', { discardComments: { removeAll: true } }],
+          preset: ["default", { discardComments: { removeAll: true } }]
         },
-        canPrint: true,
-      }),
+        canPrint: true
+      })
     ],
     splitChunks: {
-      chunks: 'all',
+      chunks: "all",
       minSize: 30000,
       maxSize: 0,
       minChunks: 1,
       cacheGroups: {
         framework: {
-          test: 'framework',
-          name: 'framework',
-          enforce: true,
+          test: "framework",
+          name: "framework",
+          enforce: true
         },
         vendors: {
           priority: -10,
           test: /node_modules/,
-          name: 'vendor',
-          enforce: true,
-        },
-      },
-    },
-  },
+          name: "vendor",
+          enforce: true
+        }
+      }
+    }
+  }
 });

+ 8 - 1
package.json

@@ -6,18 +6,25 @@
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
     "serve": "webpack-dev-server --inline --config ./config/webpack.dev.config.js",
-    "build": "webpack --config ./config/webpack.prod.config.js"
+    "build": "webpack --config ./config/webpack.prod.config.js",
+    "lint": "eslint --ext ts,tsx src/",
+    "lint:fix": "eslint --ext ts,tsx src/ --fix"
   },
   "author": "",
   "license": "ISC",
   "dependencies": {
+    "@types/react": "^16.9.35",
+    "@types/react-dom": "^16.9.8",
     "react": "^16.13.1",
     "react-dom": "^16.13.1"
   },
   "devDependencies": {
     "@babel/core": "^7.9.6",
+    "@babel/plugin-proposal-class-properties": "^7.8.3",
+    "@babel/plugin-proposal-decorators": "^7.8.3",
     "@babel/preset-env": "^7.9.6",
     "@babel/preset-react": "^7.9.4",
+    "@babel/preset-typescript": "^7.9.0",
     "autoprefixer": "^9.7.6",
     "babel-loader": "^8.1.0",
     "clean-webpack-plugin": "^3.0.0",

+ 0 - 0
src/app.jsx → src/app.tsx


+ 4 - 4
src/index.js

@@ -1,5 +1,5 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './app.jsx';
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./app.tsx";
 
-ReactDOM.render(<App />, document.getElementById('root'));
+ReactDOM.render(<App />, document.getElementById("root"));

+ 29 - 0
tsconfig.json

@@ -0,0 +1,29 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "commonjs",
+    "sourceMap": true,
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "removeComments": false,
+    "noImplicitAny": true,
+    "suppressImplicitAnyIndexErrors": true,
+    "allowSyntheticDefaultImports": true,
+    "jsx": "react",
+    "lib": ["dom", "es2015"],
+    "outDir": "./dist/",
+    "typeRoots": ["./node_modules/@types/", "./src/@types/"],
+    "baseUrl": "./src",
+    "paths": {
+      "@assets/*": ["assets/*"],
+      "@components/*": ["components/*"],
+      "@constants/*": ["constants/*"],
+      "@models/*": ["models/*"],
+      "@pages/*": ["pages/*"],
+      "@plugins": ["plugins/*"],
+      "@utils/*": ["utils/*"]
+    }
+  },
+  "compileOnSave": false,
+  "exclude": ["node_modules"]
+}