三篇長文,帶你解鎖 Webpack
,希望讀完這三篇文章,你能夠對 webpack
的各項配置有一個更為清晰的認識。
本文是第二篇,如果你還沒有閱讀《帶你深度解鎖Webpack系列(基礎篇)》,建議閱讀之後,再繼續閱讀本文。
本文會引入更多的 webpack
配置,如果文中有任何錯誤,歡迎在評論區指正,我會盡快修正。 webpack
優化部分放在了下一篇。
推薦大家參考本文一步一步進行配置,不要總是想著找什麼最佳配置,掌握之後,根據自己的需求配置出來的,就是最佳配置。
本文對應的專案地址(編寫本文時使用) 供參考:github.com/YvetteLau/w…
1. 靜態資源拷貝
有些時候,我們需要使用已有的JS檔案、CSS檔案(本地檔案),但是不需要 webpack
編譯。例如,我們在 public/index.html
中引入了 public
目錄下的 js
或 css
檔案。這個時候,如果直接打包,那麼在構建出來之後,肯定是找不到對應的 js
/ css
了。
public
目錄結構
├── public
│ ├── config.js
│ ├── index.html
│ ├── js
│ │ ├── base.js
│ │ └── other.js
│ └── login.html
複製程式碼
現在,我們在 index.html
中引入了 ./js/base.js
。
<!-- index.html -->
<script src="./js/base.js"></script>
複製程式碼
這時候,我們 npm run dev
,會發現有找不到該資原始檔的報錯資訊。
對於這個問題,我們可以手動將其拷貝至構建目錄,然後在配置 CleanWebpackPlugin
時,注意不要清空對應的檔案或資料夾即可,但是如若這個靜態檔案時不時的還會修改下,那麼依賴於手動拷貝,是很容易出問題的。
不要過於相信自己的記性,依賴於手動拷貝的方式,大多數人應該都有過忘記拷貝的經歷,你要是說你從來沒忘過。
幸運的是,webpack
為我們這些記性不好又愛偷懶的人提供了好用的外掛 CopyWebpackPlugin,它的作用就是將單個檔案或整個目錄複製到構建目錄。
首先安裝一下依賴:
npm install copy-webpack-plugin -D
複製程式碼
修改配置(當前,需要做的是將 public/js
目錄拷貝至 dist/js
目錄):
//webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
//...
plugins: [
new CopyWebpackPlugin([
{
from: 'public/js/*.js',
to: path.resolve(__dirname, 'dist', 'js'),
flatten: true,
},
//還可以繼續配置其它要拷貝的檔案
])
]
}
複製程式碼
此時,重新執行 npm run dev
,報錯資訊已經消失。
這裡說一下 flatten
這個引數,設定為 true
,那麼它只會拷貝檔案,而不會把資料夾路徑都拷貝上,大家可以不設定 flatten
時,看下構建結果。
另外,如果我們要拷貝一個目錄下的很多檔案,但是想過濾掉某個或某些檔案,那麼 CopyWebpackPlugin
還為我們提供了 ignore
引數。
//webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
//...
plugins: [
new CopyWebpackPlugin([
{
from: 'public/js/*.js',
to: path.resolve(__dirname, 'dist', 'js'),
flatten: true,
}
], {
ignore: ['other.js']
})
]
}
複製程式碼
例如,這裡我們忽略掉 js
目錄下的 other.js
檔案,使用 npm run build
構建,可以看到 dist/js
下不會出現 other.js
檔案。 CopyWebpackPlugin
還提供了很多其它的引數,如果當前的配置不能滿足你,可以查閱文件進一步修改配置。
2.ProvidePlugin
ProvidePlugin
在我看來,是為懶人準備的,不過也別過度使用,畢竟全域性變數不是什麼“好東西”。ProvidePlugin
的作用就是不需要 import
或 require
就可以在專案中到處使用。
ProvidePlugin
是 webpack
的內建外掛,使用方式如下:
new webpack.ProvidePlugin({
identifier1: 'module1',
identifier2: ['module2', 'property2']
});
複製程式碼
預設尋找路徑是當前資料夾 ./**
和 node_modules
,當然啦,你可以指定全路徑。
React
大家都知道的,使用的時候,要在每個檔案中引入 React
,不然立刻拋錯給你看。還有就是 jquery
, lodash
這樣的庫,可能在多個檔案中使用,但是懶得每次都引入,好嘛,一起來偷個懶,修改下 webpack
的配置:
const webpack = require('webpack');
module.exports = {
//...
plugins: [
new webpack.ProvidePlugin({
React: 'react',
Component: ['react', 'Component'],
Vue: ['vue/dist/vue.esm.js', 'default'],
$: 'jquery',
_map: ['lodash', 'map']
})
]
}
複製程式碼
這樣配置之後,你就可以在專案中隨心所欲的使用 $
、_map
了,並且寫 React
元件時,也不需要 import
React
和 Component
了,如果你想的話,你還可以把 React
的 Hooks
都配置在這裡。
另外呢,Vue
的配置後面多了一個 default
,這是因為 vue.esm.js
中使用的是 export default
匯出的,對於這種,必須要指定 default
。React
使用的是 module.exports
匯出的,因此不要寫 default
。
另外,就是如果你專案啟動了 eslint
的話,記得修改下 eslint
的配置檔案,增加以下配置:
{
"globals": {
"React": true,
"Vue": true,
//....
}
}
複製程式碼
當然啦,偷懶要有個度,你要是配一大堆全域性變數,最終可能會給自己帶來麻煩,對自己配置的全域性變數一定要負責到底。
3.抽離CSS
CSS打包我們前面已經說過了,不過呢,有些時候,我們可能會有抽離CSS的需求,即將CSS檔案單獨打包,這可能是因為打包成一個JS檔案太大,影響載入速度,也有可能是為了快取(例如,只有JS部分有改動),還有可能就是“我高興”:我想抽離就抽離,誰也管不著。
不管你是因為什麼原因要抽離CSS,只要你有需求,我們就可以去實現。
首先,安裝 loader
:
npm install mini-css-extract-plugin -D
複製程式碼
mini-css-extract-plugin
和extract-text-webpack-plugin
相比:
- 非同步載入
- 不會重複編譯(效能更好)
- 更容易使用
- 只適用CSS
修改我們的配置檔案:
//webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
//個人習慣將css檔案放在單獨目錄下
//publicPath:'../' //如果你的output的publicPath配置的是 './' 這種相對路徑,那麼如果將css檔案放在單獨目錄下,記得在這裡指定一下publicPath
})
],
module: {
rules: [
{
test: /\.(le|c)ss$/,
use: [
MiniCssExtractPlugin.loader, //替換之前的 style-loader
'css-loader', {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')({
"overrideBrowserslist": [
"defaults"
]
})
]
}
}
}, 'less-loader'
],
exclude: /node_modules/
}
]
}
}
複製程式碼
現在,我們重新編譯:npm run build
,目錄結構如下所示:
.
├── dist
│ ├── assets
│ │ ├── alita_e09b5c.jpg
│ │ └── thor_e09b5c.jpeg
│ ├── css
│ │ ├── index.css
│ │ └── index.css.map
│ ├── bundle.fb6d0c.js
│ ├── bundle.fb6d0c.js.map
│ └── index.html
複製程式碼
前面說了最好新建一個 .browserslistrc
檔案,這樣可以多個 loader
共享配置,所以,動手在根目錄下新建檔案 (.browserslistrc
),內容如下(你可以根據自己專案需求,修改為其它的配置):
last 2 version
> 0.25%
not dead
複製程式碼
修改 webpack.config.js
:
//webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
//...
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
],
module: {
rules: [
{
test: /\.(c|le)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader', {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')()
]
}
}
}, 'less-loader'
],
exclude: /node_modules/
},
]
}
}
複製程式碼
要測試自己的 .browserlistrc
有沒有生效也很簡單,直接將檔案內容修改為 last 1 Chrome versions
,然後對比修改前後的構建出的結果,就能看出來啦。
可以檢視更多[browserslistrc]配置項(github.com/browserslis…)
更多配置項,可以檢視mini-css-extract-plugin
將抽離出來的css檔案進行壓縮
使用 mini-css-extract-plugin
,CSS
檔案預設不會被壓縮,如果想要壓縮,需要配置 optimization
,首先安裝 optimize-css-assets-webpack-plugin
.
npm install optimize-css-assets-webpack-plugin -D
複製程式碼
修改webpack配置:
//webpack.config.js
const OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/index.js',
//....
plugins: [
new OptimizeCssPlugin()
],
}
複製程式碼
注意,這裡將 OptimizeCssPlugin
直接配置在 plugins
裡面,那麼 js
和 css
都能夠正常壓縮,如果你將這個配置在 optimization
,那麼需要再配置一下 js
的壓縮(開發環境下不需要去做CSS的壓縮,因此後面記得將其放到 webpack.config.prod.js
中哈)。
配置完之後,測試的時候發現,抽離之後,修改 css
檔案時,第一次頁面會重新整理,但是第二次頁面不會重新整理 —— 好嘛,我平時的業務中用不著抽離 css
,這個問題擱置了好多天(準確來說是忘記了)。
3月8號再次修改這篇文章的時候,正好看到了 MiniCssExtractPlugin.loader
對應的 option
設定,我們再次修改下對應的 rule
。
module.exports = {
rules: [
{
test: /\.(c|le)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: isDev,
reloadAll: true,
}
},
//...
],
exclude: /node_modules/
}
]
}
複製程式碼
4.按需載入
很多時候我們不需要一次性載入所有的JS檔案,而應該在不同階段去載入所需要的程式碼。webpack
內建了強大的分割程式碼的功能可以實現按需載入。
比如,我們在點選了某個按鈕之後,才需要使用使用對應的JS檔案中的程式碼,需要使用 import()
語法:
document.getElementById('btn').onclick = function() {
import('./handle').then(fn => fn.default());
}
複製程式碼
import()
語法,需要 @babel/plugin-syntax-dynamic-import
的外掛支援,但是因為當前 @babel/preset-env
預設中已經包含了 @babel/plugin-syntax-dynamic-import
,因此我們不需要再單獨安裝和配置。
直接 npm run build
進行構建,構建結果如下:
webpack
遇到 import(****)
這樣的語法的時候,會這樣處理:
- 以**** 為入口新生成一個
Chunk
- 當程式碼執行到
import
所在的語句時,才會載入該Chunk
所對應的檔案(如這裡的1.bundle.8bf4dc.js)
大家可以在瀏覽器中的控制檯中,在 Network
的 Tab頁
檢視檔案載入的情況,只有點選之後,才會載入對應的 JS
。
5.熱更新
- 首先配置
devServer
的hot
為true
- 並且在
plugins
中增加new webpack.HotModuleReplacementPlugin()
//webpack.config.js
const webpack = require('webpack');
module.exports = {
//....
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin() //熱更新外掛
]
}
複製程式碼
我們配置了 HotModuleReplacementPlugin
之後,會發現,此時我們修改程式碼,仍然是整個頁面都會重新整理。不希望整個頁面都重新整理,還需要修改入口檔案:
- 在入口檔案中新增:
if(module && module.hot) {
module.hot.accept()
}
複製程式碼
此時,再修改程式碼,不會造成整個頁面的重新整理。
6.多頁應用打包
有時,我們的應用不一定是一個單頁應用,而是一個多頁應用,那麼如何使用 webpack
進行打包呢。為了生成目錄看起來清晰,不生成單獨的 map
檔案。
//webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
login: './src/login.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash:6].js'
},
//...
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html' //打包後的檔名
}),
new HtmlWebpackPlugin({
template: './public/login.html',
filename: 'login.html' //打包後的檔名
}),
]
}
複製程式碼
如果需要配置多個 HtmlWebpackPlugin
,那麼 filename
欄位不可預設,否則預設生成的都是 index.html
,如果你希望 html
的檔名中也帶有 hash
,那麼直接修改 fliename
欄位即可,例如: filename: 'login.[hash:6].html'
。
生成目錄如下:
.
├── dist
│ ├── 2.463ccf.js
│ ├── assets
│ │ └── thor_e09b5c.jpeg
│ ├── css
│ │ ├── index.css
│ │ └── login.css
│ ├── index.463ccf.js
│ ├── index.html
│ ├── js
│ │ └── base.js
│ ├── login.463ccf.js
│ └── login.html
複製程式碼
看起來,似乎是OK了,不過呢,檢視 index.html
和 login.html
會發現,都同時引入了 index.f7d21a.js
和 login.f7d21a.js
,通常這不是我們想要的,我們希望,index.html
中只引入 index.f7d21a.js
,login.html
只引入 login.f7d21a.js
。
HtmlWebpackPlugin
提供了一個 chunks
的引數,可以接受一個陣列,配置此引數僅會將陣列中指定的js引入到html檔案中,此外,如果你需要引入多個JS檔案,僅有少數不想引入,還可以指定 excludeChunks
引數,它接受一個陣列。
//webpack.config.js
module.exports = {
//...
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html', //打包後的檔名
chunks: ['index']
}),
new HtmlWebpackPlugin({
template: './public/login.html',
filename: 'login.html', //打包後的檔名
chunks: ['login']
}),
]
}
複製程式碼
執行 npm run build
,可以看到 index.html
中僅引入了 index
的 JS
檔案,而 login.html
中也僅引入了 login
的 JS
檔案,符合我們的預期。
7.resolve 配置
resolve
配置 webpack
如何尋找模組所對應的檔案。webpack
內建 JavaScript
模組化語法解析功能,預設會採用模組化標準里約定好的規則去尋找,但你可以根據自己的需要修改預設的規則。
- modules
resolve.modules
配置 webpack
去哪些目錄下尋找第三方模組,預設情況下,只會去 node_modules
下尋找,如果你我們專案中某個資料夾下的模組經常被匯入,不希望寫很長的路徑,那麼就可以通過配置 resolve.modules
來簡化。
//webpack.config.js
module.exports = {
//....
resolve: {
modules: ['./src/components', 'node_modules'] //從左到右依次查詢
}
}
複製程式碼
這樣配置之後,我們 import Dialog from 'dialog'
,會去尋找 ./src/components/dialog
,不再需要使用相對路徑匯入。如果在 ./src/components
下找不到的話,就會到 node_modules
下尋找。
- alias
resolve.alias
配置項通過別名把原匯入路徑對映成一個新的匯入路徑,例如:
//webpack.config.js
module.exports = {
//....
resolve: {
alias: {
'react-native': '@my/react-native-web' //這個包名是我隨便寫的哈
}
}
}
複製程式碼
例如,我們有一個依賴 @my/react-native-web
可以實現 react-native
轉 web
。我們程式碼一般下面這樣:
import { View, ListView, StyleSheet, Animated } from 'react-native';
複製程式碼
配置了別名之後,在轉 web 時,會從 @my/react-native-web
尋找對應的依賴。
當然啦,如果某個依賴的名字太長了,你也可以給它配置一個短一點的別名,這樣用起來比較爽,尤其是帶有 scope
的包。
- extensions
適配多端的專案中,可能會出現 .web.js
, .wx.js
,例如在轉web的專案中,我們希望首先找 .web.js
,如果沒有,再找 .js
。我們可以這樣配置:
//webpack.config.js
module.exports = {
//....
resolve: {
extensions: ['web.js', '.js'] //當然,你還可以配置 .json, .css
}
}
複製程式碼
首先尋找 ../dialog.web.js
,如果不存在的話,再尋找 ../dialog.js
。這在適配多端的程式碼中非常有用,否則,你就需要根據不同的平臺去引入檔案(以犧牲了速度為代價)。
import dialog from '../dialog';
複製程式碼
當然,配置 extensions
,我們就可以預設檔案字尾,在匯入語句沒帶檔案字尾時,會自動帶上extensions
中配置的字尾後,去嘗試訪問檔案是否存在,因此要將高頻的字尾放在前面,並且陣列不要太長,減少嘗試次數。如果沒有配置 extensions
,預設只會找對對應的js檔案。
- enforceExtension
如果配置了 resolve.enforceExtension
為 true
,那麼匯入語句不能預設檔案字尾。
- mainFields
有一些第三方模組會提供多份程式碼,例如 bootstrap
,可以檢視 bootstrap
的 package.json
檔案:
{
"style": "dist/css/bootstrap.css",
"sass": "scss/bootstrap.scss",
"main": "dist/js/bootstrap",
}
複製程式碼
resolve.mainFields
預設配置是 ['browser', 'main']
,即首先找對應依賴 package.json
中的 brower
欄位,如果沒有,找 main
欄位。
如:import 'bootstrap'
預設情況下,找得是對應的依賴的 package.json
的 main
欄位指定的檔案,即 dist/js/bootstrap
。
假設我們希望,import 'bootsrap'
預設去找 css
檔案的話,可以配置 resolve.mainFields
為:
//webpack.config.js
module.exports = {
//....
resolve: {
mainFields: ['style', 'main']
}
}
複製程式碼
8.區分不同的環境
目前為止我們 webpack
的配置,都定義在了 webpack.config.js
中,對於需要區分是開發環境還是生產環境的情況,我們根據 process.env.NODE_ENV
去進行了區分配置,但是配置檔案中如果有多處需要區分環境的配置,這種顯然不是一個好辦法。
更好的做法是建立多個配置檔案,如: webpack.base.js
、webpack.dev.js
、webpack.prod.js
。
webpack.base.js
定義公共的配置webpack.dev.js
:定義開發環境的配置webpack.prod.js
:定義生產環境的配置
webpack-merge 專為 webpack
設計,提供了一個 merge
函式,用於連線陣列,合併物件。
npm install webpack-merge -D
複製程式碼
const merge = require('webpack-merge');
merge({
devtool: 'cheap-module-eval-source-map',
module: {
rules: [
{a: 1}
]
},
plugins: [1,2,3]
}, {
devtool: 'none',
mode: "production",
module: {
rules: [
{a: 2},
{b: 1}
]
},
plugins: [4,5,6],
});
//合併後的結果為
{
devtool: 'none',
mode: "production",
module: {
rules: [
{a: 1},
{a: 2},
{b: 1}
]
},
plugins: [1,2,3,4,5,6]
}
複製程式碼
webpack.config.base.js
中是通用的 webpack
配置,以 webpack.config.dev.js
為例,如下:
//webpack.config.dev.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.config.base');
module.exports = merge(baseWebpackConfig, {
mode: 'development'
//...其它的一些配置
});
複製程式碼
然後修改我們的 package.json
,指定對應的 config
檔案:
//package.json
{
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --config=webpack.config.dev.js",
"build": "cross-env NODE_ENV=production webpack --config=webpack.config.prod.js"
},
}
複製程式碼
你可以使用 merge
合併,也可以使用 merge.smart
合併,merge.smart
在合併loader
時,會將同一匹配規則的進行合併,webpack-merge
的說明文件中給出了詳細的示例。
9.定義環境變數
很多時候,我們在開發環境中會使用預發環境或者是本地的域名,生產環境中使用線上域名,我們可以在 webpack
定義環境變數,然後在程式碼中使用。
使用 webpack
內建外掛 DefinePlugin
來定義環境變數。
DefinePlugin
中的每個鍵,是一個識別符號.
- 如果
value
是一個字串,會被當做code
片段 - 如果
value
不是一個字串,會被stringify
- 如果
value
是一個物件,正常物件定義即可 - 如果
key
中有typeof
,它只針對typeof
呼叫定義
//webpack.config.dev.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
DEV: JSON.stringify('dev'), //字串
FLAG: 'true' //FLAG 是個布林型別
})
]
}
複製程式碼
//index.js
if(DEV === 'dev') {
//開發環境
}else {
//生產環境
}
複製程式碼
10.利用webpack解決跨域問題
假設前端在3000埠,服務端在4000埠,我們通過 webpack
配置的方式去實現跨域。
首先,我們在本地建立一個 server.js
:
let express = require('express');
let app = express();
app.get('/api/user', (req, res) => {
res.json({name: '劉小夕'});
});
app.listen(4000);
複製程式碼
執行程式碼(run code
),現在我們可以在瀏覽器中訪問到此介面: http://localhost:4000/api/user
。
在 index.js
中請求 /api/user
,修改 index.js
如下:
//需要將 localhost:3000 轉發到 localhost:4000(服務端) 埠
fetch("/api/user")
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.log(err));
複製程式碼
我們希望通過配置代理的方式,去訪問 4000 的介面。
配置代理
修改 webpack
配置:
//webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
"/api": "http://localhost:4000"
}
}
}
複製程式碼
重新執行 npm run dev
,可以看到控制檯列印出來了 {name: "劉小夕"}
,實現了跨域。
大多情況,後端提供的介面並不包含 /api
,即:/user
,/info
、/list
等,配置代理時,我們不可能羅列出每一個api。
修改我們的服務端程式碼,並重新執行。
//server.js
let express = require('express');
let app = express();
app.get('/user', (req, res) => {
res.json({name: '劉小夕'});
});
app.listen(4000);
複製程式碼
儘管後端的介面並不包含 /api
,我們在請求後端介面時,仍然以 /api
開頭,在配置代理時,去掉 /api
,修改配置:
//webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:4000',
pathRewrite: {
'/api': ''
}
}
}
}
}
複製程式碼
重新執行 npm run dev
,在瀏覽器中訪問: http://localhost:3000/
,控制檯中也列印出了{name: "劉小夕"}
,跨域成功,
11.前端模擬資料
簡單資料模擬
module.exports = {
devServer: {
before(app) {
app.get('/user', (req, res) => {
res.json({name: '劉小夕'})
})
}
}
}
複製程式碼
在 src/index.js
中直接請求 /user
介面。
fetch("user")
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.log(err));
複製程式碼
使用 mocker-api mock資料介面
mocker-api 為 REST API 建立模擬 API。在沒有實際 REST API 伺服器的情況下測試應用程式時,它會很有用。
- 安裝 mocker-api:
npm install mocker-api -D
複製程式碼
- 在專案中新建mock資料夾,新建 mocker.js.檔案,檔案如下:
module.exports = {
'GET /user': {name: '劉小夕'},
'POST /login/account': (req, res) => {
const { password, username } = req.body
if (password === '888888' && username === 'admin') {
return res.send({
status: 'ok',
code: 0,
token: 'sdfsdfsdfdsf',
data: { id: 1, name: '劉小夕' }
})
} else {
return res.send({ status: 'error', code: 403 })
}
}
}
複製程式碼
- 修改
webpack.config.base.js
:
const apiMocker = require('mocker-api');
module.export = {
//...
devServer: {
before(app){
apiMocker(app, path.resolve('./mock/mocker.js'))
}
}
}
複製程式碼
這樣,我們就可以直接在程式碼中像請求後端介面一樣對mock資料進行請求。
- 重啟
npm run dev
,可以看到,控制檯成功列印出來{name: '劉小夕'}
- 我們再修改下
src/index.js
,檢查下POST介面是否成功
//src/index.js
fetch("/login/account", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: "admin",
password: "888888"
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.log(err));
複製程式碼
可以在控制檯中看到介面返回的成功的資料。
進階篇就到這裡結束啦,最後一篇是優化篇,下週一帶上小板凳和瓜子來約。
最後
如果本文對你有幫助的話,給本文點個贊吧。
關注公眾號
加入技術交流群
參考: