Webpack 安裝懶人包 (置頂)
1. npm init -y
2. npm install webpack webpack-cli --save-dev
3. touch webpack.config.js
4. npm install jquery --save-dev
5. npm install -D babel-loader @babel/core @babel/preset-env
6. npm install sass-loader sass --save-dev
7. npm install --save-dev style-loader
8. npm install --save-dev css-loader
9. npm install --save-dev webpack-dev-server
10. npm install --save-dev html-webpack-plugin
如果要執行 React 不要忘記還有東西要裝
在 webpack.config.js
設定檔貼上下述程式碼:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
}, {
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
})
],
};
在 package.json
中的 script 加上下列兩項設定:
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack",
},
// 直接在 CLI 下 npm run start 可以直接打開 dev server
在 src 資料夾下的 index.js
開頭加上:
import scss from './main.scss';
import $ from 'jquery';
- 設定完成!
- 必要設定:
- 根目錄:
- index.html
- src:
- index.js
- main.scss
- 根目錄:
- 利用 npm run start 可啟動 dev server
補充:
建置 React 環境
上述的 1,2,3,5 項 Webpack, babel 等功能要先安裝,另外還還需要裝幾樣東西:
1. npm install react react-dom --save-dev
2. npm install @babel/preset-react --save-dev
修改 webpack.config.js
底下 babel 的設定:
{
presets: ['@babel/preset-env', '@babel/preset-react'],
}
- React 官方提供的 create-react-app 安裝指令:
npm install -g create-react-app
create-react-app <app 名稱>
開始介紹 Webpack
背景
我們在電腦上將 A 檔案的程式,引入到 B 檔案來使用,可以透過 node 提供的 export, require 等方式來實現,這就是模組化的過程。
但是瀏覽器不支援這種 require 的形式,瀏覽器是透過全域變數去輸出 module,所以如果引入了不同的 library 它們用了相同的變數名稱,就會發生「衝突」。
所以我們要先了解,在瀏覽器與 Node 兩個不同的環境執行 JavaScript 處理模組化是不同的。Node 用的模組化規範是 CommonJS,而瀏覽器早期是沒有模組化規範的,一直到現今的瀏覽器,才出現了 ES Modules 這個原生的規範,但是由於這個規範很新(近幾年出現的),較舊的瀏覽器無法使用,所以才會出現了一些工具,讓瀏覽器可以利用類似引用檔案的方式來實現模組化
Webpack 就是可以幫你把模組包在一起,讓你可以在瀏覽器上實現模組的一個工具
簡介
Webpack 是你可以用 import 把資源加載進來,連圖片或是 css 也可以,因此也可以做到 compile css、轉換 JavaScript 等等
- node.js 也辦不到 import 圖片 & CSS
- webpack 把所有東西都視作一個資源
安裝
https://webpack.js.org/guides/getting-started/
npm init -y
npm install webpack webpack-cli --save-dev
安裝- 執行
npx webpack
就可以進行打包了
預設行為
- 預設情況下,會把 src 這個資料夾底下的檔案,打包之後放到 dist 這個資料夾底下
- 預設的設定會去 src 資料夾底下找 index.js 這個檔案設為入口點,打包後放到 dist 之後會改名成 main.js
- 預設的情況,會在打包過程中將程式碼壓縮。
更改設定
- 在根目錄底下建立
webpack.config.js
這個設定檔 - 裡面寫上下述程式碼:
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
entry
:代表程式的入口點,預設會去找 src 資料夾底下的 index.js- 程式入口點的意思,就是要把其他 module 引入進來做事情的這個地方
filename
:代表要輸出的檔案名稱,預設為 main.jspath
代表輸出的路徑,__dirname 表示現在的資料夾,所以預設的輸出路徑為現在資料夾底下的 dist 這個資料夾mode
預設為production
,代表為生產環境的版本,正式環境的版本,所以會將程式碼進行壓縮- 將 mode 改為
development
,代表為開發模式的版本,這樣打包後,程式碼就不會被壓縮,比較能看得懂
- 將 mode 改為
在 package.json 中的 script 加上 "build" : "webpack"
就可以在 CLI 下 npm run build
這段指令來執行 webpack
- webpack 執行後就會去找到 webpack.config.js 這個設定檔
- 找到設定檔後,根據設定檔的內容打包
現代開發常會使用的 config 設定
Babel-loader
https://webpack.js.org/loaders/babel-loader/
npm install -D babel-loader @babel/core @babel/preset-env
- 在
webpack.config.js
檔案的module
當中設定好role
module: {
rules: [
{
test: /\.m?js$/, // test 代表什麼樣的檔案會被 load 進來,這邊是只要是 js 結尾或者 m js 結尾的檔案就會被 load 進來
exclude: /(node_modules|bower_components)/, // 不需要被轉換的檔案,因為 node_modules 原本就被轉換過了
use: {
loader: 'babel-loader', // 使用的 loader 為 babel-loader
options: { // options 是 babel 的轉換方式,可以直接寫在這裡,或者寫在 babelrc 裡面,這邊就不用寫了
presets: ['@babel/preset-env']
}
}
}
]
}
sass-loader
https://webpack.js.org/loaders/sass-loader/
npm install sass-loader sass --save-dev
- 在
webpack.config.js
檔案的module
當中設定好role
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
// 加上這段
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
}, {
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
devServer
- 可以在改完程式碼按下存檔的那一刻,自動完成編譯動作,自動在瀏覽器上重新整理
https://webpack.js.org/guides/development/#using-webpack-dev-server npm install --save-dev webpack-dev-server
- 在
webpack.config.js
檔案中加入 devServer contentBase
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
// 加上這一段
devServer: {
contentBase: './dist', // 最後編譯完的檔案要放哪裡
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
}, {
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
- 在 package.json 中的 script 加上
"start": "webpack-dev-server --open"
這段指令,就可以在 CLI 下npm run start
這段指令把 devServer 打開
InlineSourceMap
https://webpack.js.org/guides/development/#using-source-maps
- 可以在瀏覽器上 debug 的時候,直接顯示原始程式碼的長相,讓你更方便做 debug
- 在
webpack.config.js
加上devtool: 'inline-source-map',
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
// 加上這段
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
}, {
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
HtmlWebpackPlugin
https://webpack.js.org/plugins/html-webpack-plugin/#root
- 在打包好 js 及 css 之後,可以動態自動幫你產生 html
npm install --save-dev html-webpack-plugin
- 在
webpack.config.js
設定檔開頭多一段var HtmlWebpackPlugin = require('html-webpack-plugin');
- 在
webpack.config.js
設定檔結尾多一段plugins: [new HtmlWebpackPlugin()]
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
entry: 'index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};
gulp vs Webpack
gulp 是一個任務管理工具,他可以讓我們依照設計的劇本,去執行我們指定的 task(任務)
- 例如:
- 壓縮任務
- babel
- sass
- 定時發 API
- 這些任務可以同時進行或者按照順序進行
- 但 gulp 本身不具備打包的功能 (除非引用 webpack 的 task)
Webpack 是一個打包各項模組的工具,只是在 bundle 的過程中,這些 loader 具備一些功能,順便幫我們達成我們想要的任務
- webpack 可以藉由 loader 以及 plugin 做很多有趣的事,例如說:
- 在載入 JS 的時候順便做 uglify
- 在載入 CSS 的時候順便做 minify
- 把打包出來的檔名順便加上 hash
- 根據不同頁面打包不同的檔案,就不用一次載入全部 JS
- 支援動態引入 JS,有需要的時候才載入
- Webpack 藉由這些 loader 達成類似任務的動作
- 但是 Webpack 本身不具備 task 的功能 (除非引用了 gulp 的 plugin)