從零搭建TypeScript與React開發環境

前言

平時進行開發大多數是基於vue-cli或者create-react-app等官方或者公司內部搭建的腳手架。css

咱們業務仔作的最多就是npm i和npm run dev或者npm start,而後在router文件夾上添加路由,在views或者pages文件夾中添加業務頁面。這種快速開發對公司固然是好事,但對於開發人員來講對項目裏的webpack封裝和配置瞭解的不清楚,出問題時很容易會不知如何解決,或者不會經過webpack去擴展新功能和優化編譯速度。出去是沒多大競爭力的,並且很容易被替代。html

接下來一步一步的演示如何搭建基於TypeScript與React的一個開發環境。vue

項目代碼:github.com/zhangwinwin…
(會不定時更新)node

一、搭建webpack的基礎環境

webpack是一個開源的JavaScript模塊打包工具,其核心是解決模塊之間的依賴,把各個模塊按照特定的規則和順序組織在一塊兒,最終合併爲一個JS文件(有時會有多個)。這個過程就叫做模塊打包。react

Webpack就比如一個模塊處理工廠,咱們把源代碼交給Webpack,由它進行加工、拼裝處理,產出最終的資源文件,等待送往客戶。webpack

1.一、項目初始化

運行npm init會生成一個package.json文件,裏面包含一些項目的基本信息git

npm init
複製代碼

1.二、安裝webpack4

webpack4將命令行相關的單獨拆了出去封裝成了webpack-cli。因此得安裝webpack與webpack-cligithub

npm install webpack webpack-cli -D
複製代碼

ps:在開始以前,請確保安裝了Node.js的最新版本。web

1.二、小試牛刀

webpack4號稱零配置。它提供mode配置選項(詳情請看文檔),告知webpack使用相應模式的內置優化。vue-cli

用法以下:

// 在webpack配置文件中使用
module.exports = {
  mode: 'production'
};

// 在命令行中使用
webpack --mode=production
複製代碼
  • 建立src/main.js
console.log('hello, world')
複製代碼
  • 在package.json中配置命令
"scripts": {
    "dev": "webpack ./src/main.js --mode development"
},
複製代碼

運行 npm run dev。若是出現dist/main.js說明運行成功。

二、配置功能

  • 在根目錄建立一個webpack.config.js
  • 修改package.json
"scripts": {
  "dev": "webpack --config webpack.config.js --mode development"
},
複製代碼

2.一、配置babel

安裝依賴

npm install babel-loader @babel/core @babel/cli @babel/preset-env -D
npm install core-js regenerator-runtime -S
複製代碼

簡單說明一下:

  • Babel的核心功能包含在 @babel/core 模塊中。
  • babel提供的命令行工具@babel/cli,主要是提供babel這個命令。
  • @babel/preset-env 主要做用是對咱們所使用的而且目標瀏覽器中缺失的功能進行代碼轉換和加載 polyfill。在不進行任何配置的狀況下,它所包含的插件將支持全部最新的JS特性(ES2015,ES2016等,不包含 stage 階段),將其轉換成ES5代碼。
  • core-js和regenerator-runtime能夠模擬完整的ES2015+環境。這意味着可使用諸如Promise和Map之類的新的內置組件、Array.from之類的靜態方法、Array.prototype.includes之類的實例方法。

@babel/preset-env提供了一個useBuiltIns參數,設置值爲usage時,就只會包含代碼須要的polyfill。有一點須要注意:配置此參數的值爲usage,必需要同時設置corejs。

建立babel.config.js

module.exports = {
  presets: [
    [
      '@babel/env',
      {
        useBuiltIns: 'usage',
        corejs: 3
      }
    ]
  ]
};
複製代碼

修改webpack配置

module.exports = {
  entry: ...,
  output: ...,
  + module: {
  +  rule: [
  +    {
  +      test: /\.(js|ts)x?$/,  //jsx或者tsx文件
  +      exclude: /(node_modules)/, // 排除node_modules
  +      use: {
  +        loader: 'babel-loader'
  +      }
  +    }
  +  ]
  }
}
複製代碼

2.二、配置預處理器

npm install sass-loader dart-sass css-loader style-loader file-loader -D
複製代碼
  • 修改webpack配置
module.exports = {
  entry: ...,
  output: ...,
  module: {
    rule: [
      ...,
     + {
     +  test: /\.(c|sc|sa)ss$/,
     +   use: [
     +     'style-loader',
     +     'css-loader',
     +     {
     +       loader: 'sass-loader',
     +       options: {
     +         implementation: require('dart-sass')
     +       }
     +     }
     +   ]
     + },
     + {
     +   test: /\.(png|jpg|gif|woff|svg|ttf)$/,
     +   use: [
     +     'file-loader'
     +   ]
     + }
    ]
  }
}
複製代碼

2.三、配置HtmlWebpackPlugin

HtmlWebpackPlugin簡化了HTML文件的建立,以便爲你的webpack包提供服務。這對於在文件名中包含每次會隨着編譯而發生變化哈希的webpack bundle尤爲有用。

npm i html-webpack-plugin -D
複製代碼
  • 修改webpack配置
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
...
module.exports = {
  entry: ...,
  output: {...},
  module: {...},
+  plugins: [
+    new HtmlWebpackPlugin({
+      template: path.join(__dirname, 'public/index.html'),
+      title: 'ts-react-starter',
+      filename: 'index.html'
+    }),
+  ]
}
複製代碼
  • 建立public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
複製代碼

2.四、配置 devServer 熱更新功能

webpack-dev-server可以用於快速開發應用程序,能夠實現不刷新頁面的狀況下,更新咱們的頁面。

npm i webpack-dev-server -D
複製代碼
  • 修改webpack配置
module.exports = {
  entry: ...,
  output: {...},
  module: {...},
  plugins: [...],
 + devServer: {
 +   contentBase: path.resolve(__dirname, buildPath),
 +   compress: true,
 +   port: 9000
  }
}
複製代碼
  • 修改package.json
"scripts": {
    "dev": "webpack-dev-server --open"
},
複製代碼

三、配置react

  • 安裝依賴
npm i react react-dom react-router-dom -S
npm i @babel/preset-react -D
複製代碼
  • 修改babel.config.js
module.exports = {
  presets: [
    ...,
+   '@babel/preset-react'
  ]
};
複製代碼

3.一、小試牛刀

  • 建立src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {
  BrowserRouter as Router,
  Route
} from "react-router-dom";

import 'core-js/stable';
import 'regenerator-runtime/runtime';

const Root = document.getElementById('root');

const Test = () => <div className="test">test</div>;

ReactDOM.render(
  <Router>
    <Route path='/' component={Test}>
    </Route>
  </Router>,
  Root
);
複製代碼
  • 修改webpack.config.js中的entry爲src/index.jsx。

  • 運行npm run dev便可看到效果。

四、配置TypeScript

社區已經記錄了90%的頂級JavaScript庫。這意味着,你能夠很是高效地使用這些庫,而無需在單獨的窗口打開相應文檔。能夠經過npm來安裝使用@types

npm i @types/react @types/react-dom @types/react-router-dom typescript @babel/preset-typescript -D
複製代碼
  • 修改babel.config.js
module.exports = {
  presets: [
    ...,
+   '@babel/preset-typescript'
  ]
};
複製代碼
{
  "compilerOptions": {
    "target": "ES2016",
    "module": "commonjs", 
    "jsx": "react", 
    "strict": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "inlineSourceMap": true
  },
  "include": [
    "src"
  ]
}
複製代碼
  • 將.jsx文件改成tsx文件。
  • 從新運行npm run dev便可看到效果。

五、優化webpack

5.一、mini-css-extract-plugin

將css獨立拆包最大的好處就是js和css的改動,不會影響對方。好比我改了js文件並不會致使css文件的緩存失效。

使用方式也很簡單,你們看着文檔抄就能夠了。

npm i mini-css-extract-plugin -D
複製代碼

修改webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
 module: {
    rules: [
        ...
      {
        test: /\.(c|sc|sa)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: process.env.NODE_ENV === 'development'
            }
          },
          ...
        ]
      },
    ]
  },
  plugins: [
    ...
    new MiniCssExtractPlugin({
      filename: 'index.css'
    }),
  ],
}
複製代碼

5.二、optimize-css-assets-webpack-plugin

打包css以後還須要作css代碼壓縮,這時候須要使用optimize-css-assets-webpack-plugin這個插件,它不只能壓縮css還能優化代碼。

npm i cssnano optimize-css-assets-webpack-plugin -D
複製代碼

修改webpack.config.js

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
  plugins: [
    ...
    new OptimizeCSSAssetsPlugin({
      assetNameRegExp: /index\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }]
      },
      canPrint: true
    })
  ],
}
複製代碼

優化webpack就介紹到這裏,掘金已有不少很是好的優化文章,請自行搜索並實踐。

總結

到目前爲止,已經成功的本身搭建了一個typescript+react的開發環境。在搭建過程當中,仍是會踩不少坑的。

世上無難事,只怕有心人。動手試一試,比看半天都要好。

結尾

更多文章請移步樓主github,若是喜歡請點一下star,對做者也是一種鼓勵。

相關文章
相關標籤/搜索