平時進行開發大多數是基於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是一個開源的JavaScript模塊打包工具,其核心是解決模塊之間的依賴,把各個模塊按照特定的規則和順序組織在一塊兒,最終合併爲一個JS文件(有時會有多個)。這個過程就叫做模塊打包。react
Webpack就比如一個模塊處理工廠,咱們把源代碼交給Webpack,由它進行加工、拼裝處理,產出最終的資源文件,等待送往客戶。webpack
運行npm init會生成一個package.json文件,裏面包含一些項目的基本信息git
npm init
複製代碼
webpack4將命令行相關的單獨拆了出去封裝成了webpack-cli。因此得安裝webpack與webpack-cligithub
npm install webpack webpack-cli -D
複製代碼
ps:在開始以前,請確保安裝了Node.js的最新版本。web
webpack4號稱零配置。它提供mode配置選項(詳情請看文檔),告知webpack使用相應模式的內置優化。vue-cli
用法以下:
// 在webpack配置文件中使用
module.exports = {
mode: 'production'
};
// 在命令行中使用
webpack --mode=production
複製代碼
console.log('hello, world')
複製代碼
"scripts": {
"dev": "webpack ./src/main.js --mode development"
},
複製代碼
運行 npm run dev。若是出現dist/main.js說明運行成功。
"scripts": {
"dev": "webpack --config webpack.config.js --mode development"
},
複製代碼
安裝依賴
npm install babel-loader @babel/core @babel/cli @babel/preset-env -D
npm install core-js regenerator-runtime -S
複製代碼
簡單說明一下:
@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'
+ }
+ }
+ ]
}
}
複製代碼
npm install sass-loader dart-sass css-loader style-loader file-loader -D
複製代碼
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'
+ ]
+ }
]
}
}
複製代碼
HtmlWebpackPlugin簡化了HTML文件的建立,以便爲你的webpack包提供服務。這對於在文件名中包含每次會隨着編譯而發生變化哈希的webpack bundle尤爲有用。
npm i html-webpack-plugin -D
複製代碼
+ 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'
+ }),
+ ]
}
複製代碼
<!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>
複製代碼
webpack-dev-server可以用於快速開發應用程序,能夠實現不刷新頁面的狀況下,更新咱們的頁面。
npm i webpack-dev-server -D
複製代碼
module.exports = {
entry: ...,
output: {...},
module: {...},
plugins: [...],
+ devServer: {
+ contentBase: path.resolve(__dirname, buildPath),
+ compress: true,
+ port: 9000
}
}
複製代碼
"scripts": {
"dev": "webpack-dev-server --open"
},
複製代碼
npm i react react-dom react-router-dom -S
npm i @babel/preset-react -D
複製代碼
module.exports = {
presets: [
...,
+ '@babel/preset-react'
]
};
複製代碼
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便可看到效果。
社區已經記錄了90%的頂級JavaScript庫。這意味着,你能夠很是高效地使用這些庫,而無需在單獨的窗口打開相應文檔。能夠經過npm來安裝使用@types
npm i @types/react @types/react-dom @types/react-router-dom typescript @babel/preset-typescript -D
複製代碼
module.exports = {
presets: [
...,
+ '@babel/preset-typescript'
]
};
複製代碼
{
"compilerOptions": {
"target": "ES2016",
"module": "commonjs",
"jsx": "react",
"strict": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"inlineSourceMap": true
},
"include": [
"src"
]
}
複製代碼
將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'
}),
],
}
複製代碼
打包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,對做者也是一種鼓勵。