ES6模組化及webpack配置
webpack安裝
- 安裝 node & npm(因為webpack是基於node開發的)
- 通過 npm / yarn 的方式來安裝 webpack
安裝方式:
- 全域性安裝
- npm install -g webpack
- -g : global 全域性
- 會裝在npm預設目錄
- 好處:只需要安裝一次,本機中任何專案都可以直接使用
- 缺點:如果本機專案中所依賴的webpack版本不一致會有一些問題。
- 官方推薦安裝 本地(根據當前專案來安裝)
- 本地安裝
- npm install –save-dev webpack
- 可在node_modules 目錄中查詢;
- 不同專案可使用不同版本。
- 全域性安裝
模組化
- 把具有一定獨立功能的程式碼放到一個單獨的檔案中,每一個檔案就是一個模組。
- 優勢:管理方便、易於複用
- 解決:專案開發過程中的衝突、依賴
node出現以後,node必須有模組化,node實現了一個簡易的模組框架,並流行起來,同時為其定義一些標準:
CommonJS規範
CommonJS規範是適合使用在服務端的,是同步載入,客戶端(瀏覽器)並不適合使用,所以後來有人就參考CommonJS規範定義一些適用於web的模組化規範:
- 1.AMD(Asynchronous Module Definition),前置依賴。
- 適用於瀏覽器。
- 基於AMD的requireJS模組化庫
- 2.CMD(Common Module Definition),CMD則是依賴就近。
- 適用於伺服器
- 基於CMD的seaJS模組化庫
注意:自從出來後ES6,AMD及CMD基本不用了,而是用ES6中自帶的模組化。
ES6模組化
- 基本規則
- 1:每一個模組只加載一次, 每一個JS只執行一次, 如果下次再去載入同目錄下同檔案,直接從記憶體中讀取。 一個模組就是一個單例,或者說就是一個物件;
- 2:每一個模組內宣告的變數都是區域性變數,不會汙染全域性作用域;
- 3:模組內部的變數或者函式可以通過export匯出;
- 4:一個模組可以匯入別的模組
說明:
1. export var a=100
,那麼對應的寫法可以用*號的方式去匯入,如import * as m1 from './2';
import {a} from './2';
2. 用*號的匯入方式,對應的匯出方式可以是任意的。它得到的是一個Object物件
- 1.js:
import * as m1 from './2';
,“./2”實際是“./2.js”,可不寫字尾。 - 2.js:
export var a=120;
3. 舉例:
- 1.js:
<code>
/ 匯出一組資料
var a = 100;
var b = 200;
var c = function() {};
export {a, b, c}
</code>
- 2.js: ``` import {a, b, c} from './2';```</br>
也就是說如果要用{}的形式匯入,那麼接收的時候就需要注意:匯出的名字和接收的名字是對應的,類似解構賦值。
Babel是一個javascript編譯器,也是用node寫的,可以將ES6+轉換成Es5,但並不解析程式碼中的 import 或 require 指令。因此,我們需要一個打包工具,可用webpack。
webpack配置
webpack可以將AMD、CMD及ES6模組化程式碼編譯成CommonJS。
1.圖示:
2.核心概念
- 1.入口(entry)
- entry:指定我們的專案打包檔案的入口檔案
- entry可以接收:[string, array, object]三種類型。
- 如果我們的應用程式只有一個入口的時候,可以直接使用字串形式
- 如果我們的程式有多個入口,那麼可以使用陣列或者物件形式
- 單檔案:一個入口
- 單檔案多入口:陣列:index.html 載入了兩個或多個js
- 多檔案多入口:物件
//entry: ‘./src/1.js’,
2.輸出(output):指定打包後的檔案生成配置
- 1.打包後的檔案存放的目錄:
path: path.resolve(__dirname, “dist”),
- __dirname : 常量,返回當前檔案所在的絕對路徑
- path.resolve:返回(處理)不同作業系統的絕對路徑問題
2.生成後的檔名:
- (1)對於單個入口起點,filename 會是一個靜態名稱。filename: ‘bundle.js’;
(2)當通過多個入口起點(entry point)、程式碼拆分(code splitting)或各種外掛(plugin)建立多個 bundle,應該使用以下一種替換方式,來賦予每個 bundle 一個唯一的名稱:
- a.入口名稱: filename: “[name].bundle.js”;
- 、、、、、、
d.使用基於每個 chunk 內容的 hash:filename: “[chunkhash].bundle.js”
注意:使用hash值做檔名,是為了使每次打包生成的檔案的檔名不一樣,解決JS快取問題。<code> const webpack=require("webpack"); const path=require("path"); module.exports={ entry:{ a:"./src/1.js" }, output:{ path:path.resolve(__dirname,"dist"), filename:'bundle.js' } }; </code>
- 1.打包後的檔案存放的目錄:
3.loader
(1) 檔案打包前處理器,webpack首先會去載入指定檔案(css、js、html、txt、png等)各種資原始檔,然後進行打包,但是webpack本身只能處理js,像css被打包後可能就會執行出錯,Loader就派上用場了,Loader其實就是打包前處理器。
預處理:預先處理,webpack會呼叫各種Loader對非js的資源進行預先處理,處理完成(處理成js能夠識別的資料)以後交給webpack進行打包。(2) 在使用loader之前需要安裝指定的loader:npm install loader。
- (3)loader 也能夠使用 options 物件進行配置。
(4)在 webpack.config.js 檔案中進行配置:
rules:配置Loader載入和處理規則;test: /\.txt$/
被載入的資原始檔的字尾,use: ‘raw-loader’;
當載入的資源滿足test的時候,呼叫use指定的loader去該資源進行解析處理。<code> { ..., //配置第三方模組,比如Loader就在這裡配置 module: { rules: [ //每一個規則是一個物件 { test: /\.txt$/, use: 'raw-loader' } ] } } </code>
(4)常用的loader
- (1)raw-loader:處理源資料;
(2)file-loader: 解析並返回檔案的路徑;
<code> { test: /\.png$/, //use: 'file-loader' use: [ { loader: 'file-loader', options: { name: '[name].[ext]' } } ] } </code>
(3)url-loader:像 file loader 一樣工作,但如果檔案小於限制,可以返回 data URL
<code> { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { // 設定小於limit值生成dataURL,否則生成url limit: 819200 } } ] } </code>
- (4)css-loader:解析 CSS 檔案後,使用 import 載入,並且返回CSS程式碼;
(5)style-loader:將模組的匯出作為樣式新增到DOM中;
<code> { test: /\.css$/, use: [ // 從下向上執行,所以別寫反了!!! 'style-loader', 'css-loader' ] } </code>
- (5)json-loader
注意:webpack >= v2.0.0 預設支援匯入 JSON 檔案,不需再下載json的loader。
4.外掛(plugins)
和Loader類似,但是他是打包後執行,對打包後的檔案做進一步的處理。- 壓縮外掛:webpack.optimize.UglifyJsPlugin是webpack的核心外掛,是自帶的,直接使用。
UglifyJsPlugin與webpack.optimize.UglifyJsPlugin功能相同,但是需要安裝外掛才能用。 - ExtractTextWebpackPlugin:從 bundle 中提取文字(CSS)到單獨的檔案。
如下文程式碼所示,它會將所有的入口 chunk(entry chunks)中引用的 *.css,移動到獨立分離的 CSS 檔案。因此,你的樣式將不再內嵌到 JS bundle 中,而是會放到一個單獨的 CSS 檔案(即 styles.css)當中。 如果你的樣式檔案大小較大,這會做更快提前載入,因為 CSS bundle 會跟 JS bundle 並行載入。
- 壓縮外掛:webpack.optimize.UglifyJsPlugin是webpack的核心外掛,是自帶的,直接使用。
- 1.入口(entry)
2.配置:webpack.config.js
<code> const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { UglifyJSPlugin: './src/UglifyJSPlugin.js' }, output: { path: path.resolve(__dirname, "dist"), filename: '[name].bundle.js', //filename: '[chunkhash].bundle.js' // 設定打包後的資源的載入 publicPath: "./dist/" }, module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) } ] }, // 外掛配置 plugins: [ new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("styles.css") ] }; </code>
本地webpack執行
方法一:
1.在 package.json 新增一個 npm 指令碼(npm script);
<code> { ... "scripts": { "build": "webpack -w" }, ... } </code>
- 2.執行“npm run build”命令,可得到如下圖所示:
- 方法二:
在當前目錄下,執行“.\node_modules.bin\webpack -w”命令。
注意:”webpack -w”中的“-w”命令是監聽相關檔案是否被修改,若修改則自動重新執行webpack,不用再自己手動重啟。
全域性webpack執行
在當前目錄下,執行“webpack -w”命令。
模組熱替換
模組熱替換,Hot Module ReplaceMent(HMR)。
- 可以在應用程式執行過程中替換、新增或刪除模組,而無需重新載入整個頁面。效果上就是介面的無重新整理更新。
- 這個功能主要是用於開發過程中,對生產環境沒有什麼幫助。
- 過程:
- (1)首先需要安裝Webpack-dev-server,一個輕量的node.js express伺服器。
“npm install webpack-dev-server –save-dev”
注意:Webpack-dev-server十分小巧,這裡的作用是用來伺服資原始檔,不能替代後端的伺服器。
- (1)首先需要安裝Webpack-dev-server,一個輕量的node.js express伺服器。
複製本目錄下的 package.json 和 webpack.config.js 檔案
// package.json
<code>
{
"name": "003",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --env development",
"dev": "webpack-dev-server --env development",
"build": "webpack --env production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^2.28.0",
"webpack": "^2.3.2",
"webpack-dev-server": "^2.4.2"
}
}
</code>
// webpack.config.js
<code>
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devServer: {
host: process.env.HOST, // Defaults to `localhost`
port: 8080, // Defaults to 8080
},
entry: {
app: "./app/app.js",
},
output: {
path: path.resolve(__dirname,"build"),
filename: '[name].js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'hot replace',
}),
],
};
</code>
npm i
npm run dev 或者 npm run start 這些可以在 package.json 中配置
瀏覽器開啟 localhost:8080 埠號可以在webpack.config.js 中配置
熱模組打包的資源是存在於記憶體中的
使用熱模組能為我們的開發帶來很多便利