webpack
webpack是模組化管理工具,使用webpack可以對模組進行壓縮、預處理、按需打包、按需載入等
四個核心概念
入口entry
入口起點指webpack應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後,webpack會找出有哪些模組和庫是入口起點(直接和間接)依賴的。
輸出output
告訴 webpack 在哪裡輸出它所建立的 bundles,以及如何命名這些檔案,預設值為 ./dist。整個應用程式結構,都會被編譯到你指定的輸出路徑的資料夾中。
loader
loader 讓 webpack 能夠去處理那些非 JavaScript 檔案(webpack 自身只理解 JavaScript)。loader 可以將所有型別的檔案轉換為 webpack 能夠處理的有效模組,然後你就可以利用 webpack 的打包能力,對它們進行處理。
外掛plugins
外掛的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變數。外掛介面功能極其強大,可以用來處理各種各樣的任務。
搭建環境及配置
基本框架
全域性安裝
#全域性安裝 ( MAC 需要在 npm 前加 sodu )
npm install webpack -g
#全域性安裝webpack命令列介面
npm install webpack-cli -g
#全域性安裝一個小型的Node.js Express伺服器
npm install webpack-dev-server -g
複製程式碼
資料夾
#生成src資料夾
mkdir src config dist
複製程式碼
初始化
#初始化一個本地倉庫,方便後期將程式碼上傳到gitHub上
git init
#初始化(生成package.json)
npm init -y
複製程式碼
資料夾/檔案
touch src/index.js dist/index.html
複製程式碼
環境
#打包自動生成dist資料夾,以及dist下main.js檔案(mode是webpack4獨有)
##開發環境下
webpack --mode=development
##生產環境下
webpack --mode=production
複製程式碼
區域性安裝
#區域性安裝(安裝到開發環境)
npm install webpack webpack-cli webpack-dev-server
複製程式碼
配置
基礎配置
touch config/webpack.dev.js
rm dist/main.js src/index.js
touch src/main.js
複製程式碼
const path = require("path")
module.exports = {
//入口(一個或多個)
entry:{
//main:["other.js","./src/main.js"]
main:"./src/main.js"
},
//打包環境:development & production
mode:"development",
//出口只有一個
output:{
filename: "[name].bundle.js",
path: path.resolve(__dirname,"../dist"),
//根路徑
publicPath: "/"
}
}
複製程式碼
#打包
webpack --config=config/webpack.dev.js
#啟動服務(Project is running at http://localhost:8080/)
webpack-dev-server --config=config/webpack.dev.js
複製程式碼
配置package.json簡化命令列
"start":"webpack-dev-server --config=config/webpack.dev.js",
"build":"webpack --config=config/webpack.dev.js"
{
"name": "mingx",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"webpack": "^4.8.3",
"webpack-cli": "^2.1.4",
"webpack-dev-server": "^3.1.4"
},
"devDependencies": {},
"scripts": {
"start":"webpack-dev-server --config=config/webpack.dev.js",
"build":"webpack --config=config/webpack.dev.js"
},
"author": "",
"license": "ISC"
}
複製程式碼
#重啟
npm start
#打包
npm run build
複製程式碼
配置本地伺服器(設定預設頁面為dist裡面的內容)
devServer:{
contentBase:"dist"
}
複製程式碼
載入CSS
#生成一個css檔案
touch src/main.css
複製程式碼
<div>hello</div>
<script src="main.bundle.js"></script>
body{background-color:blueviolet;color:
require("./main.css")
複製程式碼
下載css載入器
npm install style-loader css-loader
複製程式碼
配置css loaders
module:{
rules:[
//css loaders
{
test:/\.css$/,
use:["style-loader","css-loader"]
}
]
}
複製程式碼
重新啟動(只要webpack.config.js文件有變動就需要重啟,並重新整理頁面)
npm start
錯誤資訊反饋到終端
將錯誤資訊同步到http://localhost:8080/頁面(webapck.dev.js文件devServer裡面新增overlay:true)
devServer:{
contentBase:"dist",
overlay:true
}
複製程式碼
載入html
#將dist資料夾下的index.html,引入src中
mv dist/index.html src/
複製程式碼
require("./main.css")
require("./index.html")
複製程式碼
1.下載html載入器
npm install html-loader extract-loader file-loader
複製程式碼
2.配置html loaders
{
test:/\.html$/,
use:["file-loader?name=[name].html","extract-loader","html-loader"]
//使用順序從後往前
//1.html-loader找到html檔案
//2.extract-loader將index.html跟生成的bundle.js進行分割
//3.file-loader為載入的檔案起名字
}
{
test:/\.html$/,
use: [
{
loader: "file-loader",
option: {
name: "[name].html"
}
},
{
loader: "extract-loader"
},
{
loader: "html-loader"
}
]
}
複製程式碼
#刪除dist裡面的檔案
rm -rf dist/main.bundle.js dist/index.bundle.html
複製程式碼
3.打包、重啟
npm run build
npm start
複製程式碼
載入器圖片
#生成
mkdir src/images
複製程式碼
1.下載url載入器
npm install url-loader
複製程式碼
2.配置image loaders
{
//匹配到.jpg|png|svg|gif結尾的檔案
test:/\.(jpg|png|svg|gif)$/,
//多個loader需要從後到前進行解析(大於10kb打包)
use:["url-loader?limit=10&name=images/[name]-[hash:8].[ext]"]
}
複製程式碼
3.打包、重啟
載入JS
使用babel轉換JS
var a = () => {
console.log("one more time")
}
複製程式碼
下載
#安裝babel-core
npm install babel-core
#生成.babelrc檔案( babelrc檔案的本質是json ,rc為自動載入的檔案)
touch .babelrc
#下載庫,將ES6轉為ES5
npm install babel-plugin-transform-es2015-arrow-functions
複製程式碼
配置.babelrc 檔案
{
"plugins":[
"transform-es2015-arrow-functions"
]
}
複製程式碼
#安裝babel
sudo npm install babel-cli -g
#main.js使用babel
babel src/main.js
複製程式碼
#安裝babel-loader
npm install babel-loader
複製程式碼
配置JS loaders
{
test:/\.js$/,
use:["babel-loader"],
//排除node_modules中的JS檔案
exclude:/node_modules/
}
複製程式碼
#刪除dist裡面的檔案
rm -rf dist/main-bundle.js dist/index.html dist/images
#重新啟動、打包
npm start
npm run build
複製程式碼
檢視dist/main.bundle.js (中有ES6被解析為ES5)
更好的解決JS語法:polyfill / preset / transform
var a = async () => {
await console.log("one more time");
console.log('two')
}
{
"plugins":[
"transform-es2015-arrow-functions",
"async-to-promises"
]
}
複製程式碼
#將async轉為promise
npm install babel-plugin-async-to-promises
#main.js使用babel
babel src/main.js
複製程式碼
polyfill會在預編譯之前編譯指定的東西(缺點:生成環境變數的汙染)
#安裝polyfill
npm install babel-polyfill
複製程式碼
配置JS loaders
entry:{
main:["babel-polyfill","./src/main.js"]
}
複製程式碼
babel-polyfill中選擇對應的內容轉化指定的語法(觀察main.bundel.js的大小)
entry:{
main:["core-js/fn/promise","./src/main.js"]
},
複製程式碼
#比polyfill更好的方式:安裝環境變數
npm install babel-preset-env
複製程式碼
{
"presets":[
"env",
{
"debug":true
}
]
}
複製程式碼
{
"presets":[
[
"env",
{
"tartgets":{
"browsers":["last 2 versions"]
},
"debug":true
}
]
],
"plugins":[
"transform-runtime"
]
}
複製程式碼
#安裝外掛:transform-runtime
npm install babel-plugin-transform-runtime
複製程式碼
require("babel-runtime/regenerator")
require("./main.css")
require("./index.html")
var a = async args => {
const {a, b} = args
await console.log("one more time", a, b);
console.log('two')
}
a({a:12,b:23});
複製程式碼
#main.js使用babel
babel src/main.js
複製程式碼
搭建腳手架
實時報錯、服務端和客戶端實時渲染...
#安裝express
npm install express
#建立server資料夾用於啟動服務
mkdir src/server
#建立入口檔案和配置伺服器的檔案
touch src/server/main.js src/server/express.js
複製程式碼
"dev":"node src/server/main.js"
//將ES6轉為ES5
require("babel-register")
//執行express檔案
require("./express")
//啟動一個伺服器
import express from 'express';
import path from 'path';
//建立伺服器
const server = express()
//監聽埠號 8080
server.listen(8080,() => {
console.log("server is running...")
})
複製程式碼
配置服務啟動頁面
#監聽程式碼
npm install webpack-dev-middleware
複製程式碼
//啟動一個伺服器
import express from 'express';
import path from 'path';
//建立伺服器
const server = express()
//配置啟動路徑
const staticMiddleware = express.static("dist")
//監聽程式碼
const webpack = require("webpack")
const config = require("../../webpack.dev")
//使用webpack把config傳進去作為例項
const compiler = webpack(config)
//使用下載的webpack-dev-middleware
const webpackDevMiddleware = require("webpack-dev-middleware")(compiler,config.devServer)
//【執行】server
server.use(webpackDevMiddleware)
// 【使用路徑】
server.use(staticMiddleware)
//監聽埠號 8080
server.listen(8080,() => {
console.log("server is running...")
})
複製程式碼
npm run dev
前端熱更新
#配置熱更新
npm install webpack-hot-middleware
複製程式碼
//熱更新
const webpackHotMiddleware = require("webpack-hot-middleware")(compiler)
//【使用熱更新】
server.use(webpackHotMiddleware)
複製程式碼
配置熱更新
//引入webpack
const webpack = require('webpack');
//新增
module.exports = {
devServer:{
//熱更新
hot:true,
},
//外掛
plugins:[
new webpack.HotModuleReplacementPlugin()
]
」
require("webpack-hot-middleware/client")
複製程式碼
後端熱更新
#安裝全域性的nodemon進行監聽(後端)
sudo npm install nodemon -g
複製程式碼
配置監聽
"dev":"nodemon --watch config --watch src/server src/server/main.js"
複製程式碼
服務端熱更新
#服務端監聽,安裝外掛
npm install html-webpack-plugin
複製程式碼
配置後端熱更新
//引入html-webpack-plugin,並且生成例項
const HTMLWebpackPlugin = require("html-webpack-plugin");
//更改html loaders,去除和"html-webpack-plugin"外掛功能中相同的部分
{
test: /\.html$/,
use:["html-loader"]
}
//外掛
plugins:[
new webpack.HotModuleReplacementPlugin(),
//新增外掛HTMLWebpackPlugin
new HTMLWebpackPlugin({
template:"./src/index.html"
})
]
require("webpack-hot-middleware/client?reload=true")
複製程式碼
優化熱更新重複編譯和動態建立檔案的問題
npm install webpack-mild-compile
複製程式碼
require("webpack-mild-compile")
複製程式碼
藉助webpack、node.js、瀏覽器實現除錯
"dev":"nodemon --inspect --watch config --watch src/server src/server/main.js
複製程式碼
問題:[nodemon] app crashed - waiting for file changes before starting...
解決:我憑藉直覺改了src/server/express.js裡面監聽的埠路徑-_-!
React
npm install react react-dom
#建立react入口檔案
touch src/app.js
複製程式碼
//引入babel檔案解析ES6
require("babel-register");
//引入將react入口檔案
require("./app");
//新增根目錄
<div id="react-root"></div>
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hi kiwi</h1>,
document.getElementById("react-root")
)
複製程式碼
解析jsx
下載babel-preset-react
npm install babel-preset-react
複製程式碼
配置babel-preset-react
{
"presets":[
[
"env",
{
"tartgets":{
"browsers":["last 2 versions"]
},
"debug":true
}
],
"babel-preset-react"
],
"plugins":[
"transform-runtime"
]
}
複製程式碼
npm run dev
複製程式碼
Sass
npm install node-sass sass-loader
touch src/main.sass
複製程式碼
require("./main.sass")
//sass
{
test: /\.sass$/,
use: ["style-loader", "css-loader","sass-loader"]
}
複製程式碼
jQuery
npm install jquery
複製程式碼
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
複製程式碼
Bootstrap
npm install bootstrap
複製程式碼
import 'bootstrap/dist/css/bootstrap.css'
//需要先安裝jquery 和 popper.js
import 'bootstrap/dist/js/bootstrap.js'
複製程式碼
npm install popper.js
複製程式碼
plugins: [
new webpack.ProvidePlugin({
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
]
複製程式碼