WebPack4接入TypeScript開發

接入TypeScript

1、添加開發依賴


npm install --save-dev typescript awesome-typescript-loader source-map-loader

2、創建 tsconfig.json 文件:

./node_modules/.bin/tsc --init

3、安裝@types/react,@types/react-dom

npm install @types/react @types/react-dom --save

4、添加webpack的loader

npm install awesome-typescript-loader -D
npm install source-map-loader -D

5、編輯tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "sourceMap": true,                        /* Generates corresponding '.map' file. */
    "outDir": "./dist/",                      /* Redirect output structure to the directory. */
    "strict": true,                           /* Enable all strict type-checking options. */
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
  },
  "include": [
    "./src/**/*"
  ]
}

6、 編輯 webpack.typescript.js

6.1 添加tsloader , source-map-loader
6.2 添加reslove,設置文件後綴補全順序
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');


module.exports = {
  mode: 'development',
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js'
  },
  devtool: "source-map",
  devServer: {
    contentBase: path.resolve(__dirname, 'build'),
    compress: true,
    port: 8080
  },
  optimization: {
    splitChunks: {
      // include all types of chunks
      chunks: 'all'
    }
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Output manager',
      template: './src/index.html'
    })
  ],
  module: {
    rules: [
      { 
        test: /\.ts[x]?$/, 
        loader: "awesome-typescript-loader" 
      },
      { 
        enforce: "pre", 
        test: /\.ts[x]$/, 
        loader: "source-map-loader" 
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
    ]
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json", ".png"],
  },
}

7、 創建一個TypeScript組件

import * as React from "react";

export interface HelloProps { 
    compiler: string; 
    framework: string; 
}

export const Hello = (props: HelloProps) => <h1>Hello from {props.compiler} and {props.framework}!</h1>;

8、 創建一個TypeScript入口文件

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

import { Hello } from "./components/Hello";

ReactDOM.render(
    <Hello compiler="TypeScript" framework="React" />,
    document.getElementById("root")
);

9、 在package.json的script中添加一條命令buildTS

  "scripts": {
    "buildTS": "./node_modules/.bin/webpack-cli --config webpack.typescript.js",
  },

10、編譯輸出頁面

npm run buildTS

11、使用sourceMap調試

devtool: "source-map",

image

然而vue-cli腳手架搭建的工程,開發環境使用的是eval-source-map,生產環境用的是source-map。不管怎麼說的,其實用起來感覺都差不多。但是,直接將sourceMap放入打包後的文件,會明顯增大文件的大小,不利於靜態文件的快速加載;而外聯.map時,.map文件只會在F12開啓時進行下載(sourceMap主要服務於調試),故推薦使用外聯.map的形式。

參考文檔: sourceMap文檔

12、使用devServer開發

安裝webpack-dev-server,?代碼可以自動更新。

npm install --save-dev webpack-dev-server

webpack-dev-server有很多的配置項,其中之一是--config,這個可以讓我們啓動多個server,因爲每一個-dev-server相關的配置都在--config配置的webpack.config.js中指定。

"scripts": {
    "startTS": "webpack-dev-server --open --color --hot --config webpack.config.js",
  },

13、安裝antd-mobile

antd-mobile

$ npm install antd-mobile --save

這裏剛開始的時候,總是在提示babel相關的錯誤,找不到babel-core或者找不到babel-loader,一開始按照常規思路,缺什麼裝什麼,後來發現,這似乎是永無止境。那麼及時的調整思路,

  1. 先去google上看看,發現好多人說是babel升級到7導致的。但是按照上面的建議處理後,發現沒有效果。
  2. 把babel的錯誤,複製出來,百度看看, 發現有一個哥們遇到了這個問題,他的解決方法如下:
npm  install -D babel-loader @babel/core @babel/preset-env webpack

不過我第一次裝了之後發現沒用,後來乾脆把package.json中的babel-loader@babel/core都刪掉,然後執行這條命令,發現可以了。

這個步驟,其實可以換種思路,當我們發現這些問題的時候,應該有如下幾種思路:

1. 去搜索引擎搜索
2. 去插件的官網查看,最近有沒有版本升級,以及這個插件的原理是什麼
3. 是在沒辦法,就去查看插件的源碼,當然這是很花費時間的

14、使用typeScript開發項目

15、接入F2圖表

1)、 安裝F2圖表

npm install @antv/f2 --save

2)、 使用F2圖表

const F2 = require('@antv/f2');

3)、實現第一個組件


import React from 'react';
const F2 = require('@antv/f2');

class SimpleChart extends React.Component{
    constructor(props){
        super(props);
        // F2 對數據源格式的要求,僅僅是 JSON 數組,數組的每個元素是一個標準 JSON 對象。
        this.state = {
            data : [
                { genre: 'Sports', sold: 275 },
                { genre: 'Strategy', sold: 115 },
                { genre: 'Action', sold: 120 },
                { genre: 'Shooter', sold: 350 },
                { genre: 'Other', sold: 150 },
            ]
        };
    }

    componentDidMount() {
        // Step 1: 創建 Chart 對象
        this.chart = new F2.Chart({
            id: 'myChart',
            pixelRatio: window.devicePixelRatio // 指定分辨率
        });
        // Step 2: 載入數據源
        this.chart.source(this.state.data);
        // Step 3:創建圖形語法,繪製柱狀圖,由 genre 和 sold 兩個屬性決定圖形位置,genre 映射至 x 軸,sold 映射至 y 軸
        this.chart.interval().position('genre*sold').color('genre');
        // Step 4: 渲染圖表
        this.chart.render();
    }

    render(){
        return (
            <canvas id="myChart" width="320" height="260"></canvas>
        );
    }
}


export default SimpleChart;


4)、使用React Hooks實現


import React, { useState, useEffect } from 'react';
// import { useState, useEffect } from 'react';
const F2 = require('@antv/f2');

function SimpleChartHooks(){
    const myRef = React.createRef();
     // F2 對數據源格式的要求,僅僅是 JSON 數組,數組的每個元素是一個標準 JSON 對象。
    const [data, setdata] = useState(
      [
            { genre: 'Sports', sold: 275 },
            { genre: 'Strategy', sold: 115 },
            { genre: 'Action', sold: 120 },
            { genre: 'Shooter', sold: 350 },
            { genre: 'Other', sold: 150 },
        ]
    );

    useEffect(() => {
        console.log(myRef,myRef.current.id, data);
        // Step 1: 創建 Chart 對象
        const chart = new F2.Chart({
            id: 'myChart2',
            pixelRatio: window.devicePixelRatio // 指定分辨率
        });
        // Step 2: 載入數據源
        chart.source(data);
        // Step 3:創建圖形語法,繪製柱狀圖,由 genre 和 sold 兩個屬性決定圖形位置,genre 映射至 x 軸,sold 映射至 y 軸
        chart.interval().position('genre*sold').color('red');
        // Step 4: 渲染圖表
        chart.render();
    });

    return (
        <canvas ref={myRef} id="myChart2" width="320" height="260"></canvas>
    );

}

export default SimpleChartHooks;


16、ReactHooks使用

16.1、使用RectHooks開發一個組件

16.2、使用ReactHooks更新數據狀態

17、開啓package-lock.json

之前一直以爲是npm的問題,然後一直按照這個思路走,結果總是不對。其實這種思考方式太線性了。首先我們要清楚整個業務有多少個步長,然後一步一步去排查問題。否則很難快速定位到問題的所在。

image.png

18、在webpack項目中使用Loader要注意的點

image.png

在rules中的配置

  { 
    test: /\.tsx?$/, 
    use: [
      {
        loader: 'babel-loader',
        options: babelrc
      },
      { 
        loader: 'ts-loader'
      },
    ]
  },

注意TypeScript導出的類型,可能是const。

19、處理scss文件

使用樣式文件

import * as React from "react";
import styles from './index.scss'

export interface HelloProps { 
    compiler: string; 
    framework: string; 
}

export const Hello = (props: HelloProps) => {
    return (
        <div className={styles.box}>
            <h1>Hello from {props.compiler} and {props.framework}!</h1>
        </div>
    );
};

加載規則

const typingsForCssModulesLoaderConf = {
  loader: 'typings-for-css-modules-loader',
  options: {
    modules: true,
    namedExport: true,
    camelCase: true,
    sass: true
  },
};

多個loader綜合配置

 {
    test: /\.[s]*css/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      use: [typingsForCssModulesLoaderConf,'sass-loader'],
    }),
  },

20、如何處理結構化的scss文件

本地安裝sass-loader ,然後再loader中使用就可以了。

TypeScript使用scss

待解決問題?

21、happyLoader是什麼, 怎麼使用?好用嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章