webpack 4 問世了!html
這個流行的模塊打包工具進行了大規模的升級。node
webpack4,有什麼更新?大幅度的性能優化,零配置和明智的默認配置。react
webpack是一個強力和有着不少獨特功能的工具,可是他的一大痛點在於他的配置文件webpack
給中大型項目提供一個配置文件不是什麼大問題。你甚至沒法離開它。然而,對於一些較小型應用來講就有點麻煩了,尤爲是你在心血來潮想開始作一些好玩的app的時候。git
這也是Parcel吸引人的緣由github
如今的好消息是webpack 4 默認不再須要一個配置文件了!web
建立一個目錄而後進入npm
mkdir webpack-4-quickstart && cd $_
複製代碼
初始化package.json:json
npm init -y
複製代碼
安裝webpack4:
npm i webpack --save-dev
複製代碼
咱們也須要安裝另一個包:webpack-cli
npm i webpack-cli --save-dev
複製代碼
而後打開package.json添加構建腳本:
"scripts": {
"build": "webpack"
}
複製代碼
關閉保存
試着運行
npm run build
複製代碼
而後咱們看到
ERROR in Entry module not found: Error: Can't resolve './src' in '~/webpack-4-quickstart' 複製代碼
webpack 4 須要在./src目錄下找一個入口文件!若是你不知道這是什麼意思,請參考我以前的文章
簡要來講:webpack須要這個入口文件來開始js代碼的打包。
在之前的版本里webpack的入口文件須要在配置文件webpack.config.js裏指定。
可是如今不用指定了,它會默認選擇./src/index.js這個文件。
測試這個新特性很容易,建立一個./src/index.js
:
console.log(`I'm a silly entry point`);
複製代碼
從新構建:
npm run build
複製代碼
你會在~/webpack-4-quickstart/dist/main.js
獲得你打包後的文件。
什麼?等一下。都不須要指定輸出文件嗎?是的。
在webpack 4 中不須要指定入口和出口文件。
webpack的真正本領是代碼拆分。可是相信我,有一個零配置的工具能夠加速你的進程。
因此這就是第一個新特性:他會把./src/index.js默認爲入口文件,把打包後的文件放在./dist/main.js。
下一章後咱們能看到另外一個有用的特性:生產和開發模式。
在webpack中擁有兩份配置文件是常事。
一個典型的項目應該有:
在webpack4中你可以不寫一行配置。
怎麼作到的?
webpack 4介紹了生產和開發模式。
實際上若是你關注過npm run build
的輸出信息你會看到這個警告:
The ‘mode’ option has not been set. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults for this environment.
這表明什麼?咱們看看。
打開package.json文件添加以下腳本
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
複製代碼
如今運行:
npm run dev
複製代碼
查看./dis/main.js文件。你看到了什麼?嗯,我知道,他沒有被壓縮!
如今這樣:
npm run build
複製代碼
如今再看,你看到什麼?一個壓縮後的文件!
是的!
生產模式開啓了一系列額外的優化。包括minification, scope hoisting, tree-shaking等。
另外一邊開發模式爲速度作了優化,除了提供一個沒有壓縮的包之外沒有作額外的事。
因此這是第二個新特性:生產和開發模式。
在webpack4你不須要一行配置,只須要一個--mode選項。
我喜歡webpack4的零配置,可是,若是我要覆蓋默認的入口或者出口配置要怎麼作呢?
在package.json
裏配置他們。
這是一個例子
"scripts": {
"dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js",
"build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}
複製代碼
現代JavaScript大可能是用ES6寫的。
可是不是全部瀏覽器都知道怎麼處理ES6。咱們須要作一些轉換。
這個轉換的步驟叫作transpiling。transpiling是指把ES6轉換成瀏覽器可以識別的代碼。
webpack自己並不知道如何去轉換,可是它有loaders。把他們想象成轉換器。
babel-loader是webpack的一個loader,能夠轉換ES6以上的代碼到ES5。
爲了使用這個loader咱們須要去安裝一系列的依賴。特別是:
來安裝吧:
npm i babel-core babel-loader babel-preset-env --save-dev
複製代碼
下一步咱們在項目目錄下創建一個.babelrc文件用來配置Babel。
{
"presets": [
"env"
]
}
複製代碼
在這裏咱們有兩個途徑去配置babel-loader:
--module-bind
哦,我知道你在想什麼了。webpack4把本身定位爲一個零配置的工具。爲何咱們又要寫配置文件了呢。
webpack 4的零配置適用於:
這就夠了。對於loaders咱們仍然須要使用配置文件。
我曾關於這件事問過Sean。在webpack4中loaders是否和webpack3中沒有區別?有計劃對這些通用的loaders好比babel-loader提供零配置嗎?
他的回答是:
在將來的版本(v4以後,多是4.x或者5.0),咱們已經開始探索預設或附加系統如何幫助咱們定義這一點。咱們不想要的是:把一堆東西塞到核心代碼裏去。咱們須要的是:可以支持擴展。
對於如今來講你仍必須依賴webpack.config.js。
建立一個名叫webpack.config.js
的文件而後配置loader:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
複製代碼
沒有必要去指定入口文件除非你想指定。
下一步打開./src/index.js而後寫一些ES6代碼:
const arr = [1, 2, 3];
const iAmJavascriptES6 = () => console.log(...arr);
window.iAmJavascriptES6 = iAmJavascriptES6;
複製代碼
最後打包:
npm run build
複製代碼
而後去./dist/main.js看看轉換後的代碼。
還有一種使用webpack loaders的方法。
--module-bind
選項讓你從命令行指定loaders。謝謝Cezar指出了這一點。
這個選項並非webpack 4獨有的。3開始就有了。
你能夠這樣在package.json中使用:
"scripts": {
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
}
複製代碼
而後你就能夠開始構建了。
而後我並非很喜歡這種方法(不喜歡太長的npm腳本),儘管如此它頗有趣。
若是你已經安裝配置好了babel這會很簡單。
安裝React:
npm i react react-dom --save-dev
複製代碼
添加babel-preset-react
:
npm i babel-preset-react --save-dev
複製代碼
在.babelrc裏配置preset
{
"presets": ["env", "react"]
}
複製代碼
這樣就能夠了。
如Conner Aiken建議的你能夠配置babel-loader也去加載**.jsx**文件。這在你使用jsx擴展名的時候頗有用。
打開webpack.config.js
而後這樣配置:
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
複製代碼
測試是否搭好你能夠在./src/App.js
裏建立一個React組件。
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
return (
<div> <p>React here!</p> </div>
);
};
export default App;
ReactDOM.render(<App />, document.getElementById("app")); 複製代碼
而後在./src/idnex.js
中引入:
import App from "./App";
複製代碼
從新構建
webpack須要兩個額外的組件去處理HTML:html-webpack-plugin和html-loader。
添加這兩個依賴:
npm i html-webpack-plugin html-loader --save-dev
複製代碼
而後更新webpack的配置
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
]
};
複製代碼
在./src/index.html
新建一個HTML文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>webpack 4 quickstart</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>
複製代碼
運行:
npm run build
複製代碼
查看./dist
目錄。你會看到運行的結果。
沒有必要再你的HTML文件中引入你的JavaScript:它會自動地注入進去。
在瀏覽器打開./dist/index.html
:你能夠看到React組件運行起來了!
如你所見在處理HTML上沒有什麼變化。
webpack 4仍然是一個主要目標是js的模塊打包工具。
但有個將HTML做爲模塊的方法(HTML做爲入口)。
webpack不知道怎麼去提取CSS到文件中。
在以前這是extract-text-webpack-plugin的工做。
不幸的是這個插件在webpack 4表現並很差。
Michael Ciniawsky說:
維護extract-text-webpack-plugin是一個很大的負擔,並且這不是第一次由於這個問題使得升級webpack的主要版本變得困難。
mini-css-extract-plugin是來解決這些問題的。
提示:你須要把webpack升級到4.2.0.0,否則這個插件沒法運行!
安裝它:
npm i mini-css-extract-plugin css-loader --save-dev
複製代碼
而後創建一個CSS文件用來測試
/* */
/* CREATE THIS FILE IN ./src/main.css */
/* */
body {
line-height: 2;
}
複製代碼
配置plugin和loader:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
};
複製代碼
最後在入口文件中引入CSS:
//
// PATH OF THIS FILE: ./src/index.js
//
import style from "./main.css";
複製代碼
構建:
npm run build
複製代碼
查看./dist目錄,你應該能看到CSS的結果!
結論:extract-text-webpack-plugin在webpack 4中不能用了。請使用mini-css-extract-plugin。
在你改變代碼後運行npm run dev
?這不是個理想的作法。花幾分鐘去配置下webpack的開發服務。一旦配置了webpack dev server 它會在瀏覽器中加載你的app。
只要你改變了文件,它會自動地刷新瀏覽器的頁面。
安裝下面的包來搭建webpack dev server:
npm i webpack-dev-server --save-dev
複製代碼
而後打開package.json
調整腳本:
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
}
複製代碼
保存關閉。
如今運行:
npm run start
複製代碼
你就能看到webpack dev server在瀏覽器中加載你的應用了。
webpack dev server很是適合用來開發。(並且它能使得的React Dev Tools在瀏覽器中正常的工做)
本教程在Github上的連接 => webpack-4-quickstart
我知道早就有不少webpack的列表可是這裏是個人:一系列優秀的webpack4資源 => awesome-webpack-4
這裏必定還要提一下Juho Vepsäläinen的SurviveJS webpack 4