Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

初始化React + TypeScript项目 #11

Open
miyuesc opened this issue Jun 28, 2019 · 0 comments
Open

初始化React + TypeScript项目 #11

miyuesc opened this issue Jun 28, 2019 · 0 comments

Comments

@miyuesc
Copy link
Owner

miyuesc commented Jun 28, 2019

summary_start
出于我对react的强烈好奇,我终于开始了react的基础学习。百度了一下发现大部分都是直接采用create-react-app来初始化项目的,但是因为之前用的Vue也需要配置webpack,so...
summary_end

1. 建立项目并初始化

找到你的工作区文件夹,新建一个项目文件夹,然后初始化你的项目。

// mkdir [你的项目名称]
mkdir react-ts-demo
cd react-ts-demo
yarn init

2. 安装开发依赖包

I. 安装React,ReactDom依赖

yarn add react
yarn add react-dom
// 可以写在一行,同时引入
// yarn add react react-dom

II. 安装React类型库

由于React是用js和jsx文件写的,需要引入类型库来识别ts/tsx文件

yarn add --dev @types/react @types/react-dom
// 使用--dev,将依赖包安装到开发环境devDependencies下

III. 安装ts

yarn add --dev typescript ts-loader

IV. 安装webpack

yarn add --dev webpack webpack-cli webpack-dev-server webpack-merge

V. 安装webpack插件

yarn add --dev source-map-loader html-webpack-plugin clean-webpack-plugin uglifyjs-webpack-plugin

3. 项目配置

在根目录下新建config文件夹,存放项目配置文件。

I. 配置通用文件路径paths.js

// path: ./config/path.js
const path = require("path");
const fs = require("fs");

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

module.exports = {
  appBuild: resolveApp("build"),
  appPublic: resolveApp("public"),
  appIndex: resolveApp("src/index.tsx"),
  appHtml: resolveApp("public/index.html")
};

II. 通用webpack配置webpack.config.js

在config下新建webpack文件夹,存放webpack配置文件。

// path: ./config/webpack/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const paths = require("../paths");

module.exports = {
  resolve: {
    extensions: [".tsx", ".ts", ".js", ".json"]
  },
  devtool: "source-map",
  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.js$/,
        loader: "source-map-loader"
      },
      {
        test: /\.(ts|tsx)$/,
        loader: "ts-loader"
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "React + Typescript Demo",
      favicon: "./public/logo.ico",
      template: paths.appHtml,
      inject: false
    })
  ]
};

III. 开发环境webpack配置webpack.config.dev.js

const webpack = require("webpack");
const merge = require("webpack-merge");

const paths = require("../paths");
const commonConfig = require("./webpack.config.common");

module.exports = merge.smart(commonConfig, {
  mode: "development",
  entry: paths.appIndex, // 入口文件
  output: {
    filename: "static/js/[name]-bundle-[hash:8].js"
    // 使用hash命名
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin()
  ],
  devServer: {
    // 开启前端路径回路映射,子路径映射到根路径,由前端路由框架来解析
    // historyApiFallback: true,
    // 关闭 Host 检查,同网段其他设备,可通过内网 IP 访问本机服务(需要配合 host: '0.0.0.0')使用
    // disableHostCheck: true,
    // host: "0.0.0.0",
    port: "8000",
    inline: true,
    hot: true
    // 请求代理服务
    // proxy: {
    //   "/api": {
    //     // 这里改为项目后端 API 接口 Host
    //     target: "http://server.address:post",
    //     // 支持跨域调用
    //     changeOrigin: true
    //   }
    // }
  }
});

IV. 生产环境webpack配置webpack.config.build.js

即打包配置。

const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

const paths = require("../paths");
const commonConfig = require("./webpack.config.common");

module.exports = merge.smart(commonConfig, {
  mode: "production",
  entry: paths.appIndex,
  output: {
    path: paths.appBuild,
    filename: "static/js/[name]-[hash:8].js"
  },
  optimization: {
    minimizer: [
      // 压缩 js
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true
      })
    ],
    splitChunks: {
      // 切割代码块,提取为独立的 chunk 文件
      chunks: "all"
    }
  },
  plugins: [
    // 每次编译之前,清空上一次编译的文件
    new CleanWebpackPlugin([paths.appBuild], {
      root: process.cwd()
    })
  ]
});

V. tsconfig.json 配置

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true, // 允许合成默认导出
    "jsx": "react",
    "lib": ["es6", "dom"], // 若使用更高版本的ES,可以在此次改
    "module": "esnext",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "rootDir": "src",
    "sourceMap": true,
    "strict": true,
    "target": "es5"
  },
  "exclude": ["node_modules", "build"]
}

4. 创建入口文件

I. 在public文件夹下新建index.html文件。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <title><%= htmlWebpackPlugin.options.title %></title>
    <link rel="icon" href="/<%= htmlWebpackPlugin.options.favicon %>" />
    <% for (let css in htmlWebpackPlugin.files.css) { %>
    <link href="/<%=htmlWebpackPlugin.files.css[css] %>" rel="stylesheet" />
    <% } %>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <% for (let chunk in htmlWebpackPlugin.files.chunks) { %>
    <script
      type="text/javascript"
      src="/<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"
    ></script>
    <% } %>
  </body>
</html>

II. 在public文件夹下引入项目网站favicon:logo.ico

III. 在src文件夹下新建index.tsx文件

import React from "react";
import ReactDOM from "react-dom";

ReactDOM.render(<div>Hello world!</div>, document.getElementById("root"));

5. 添加项目启动脚本

在package.json文件内添加script运行命令。

{
	"script": {
		"start": "webpack-dev-server --open --colors --config config/webpack/webpack.config.dev.js",
		"build": "webpack --progress --colors --config config/webpack/webpack.config.build.js"
	}
}

6. 启动项目

在根目录下运行

yarn start
@miyuesc miyuesc added this to the 技术向 milestone Jul 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant