接入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",
然而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,一開始按照常規思路,缺什麼裝什麼,後來發現,這似乎是永無止境。那麼及時的調整思路,
- 先去google上看看,發現好多人說是babel升級到7導致的。但是按照上面的建議處理後,發現沒有效果。
- 把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的問題,然後一直按照這個思路走,結果總是不對。其實這種思考方式太線性了。首先我們要清楚整個業務有多少個步長,然後一步一步去排查問題。否則很難快速定位到問題的所在。
18、在webpack項目中使用Loader要注意的點
在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中使用就可以了。