Webpack 基本操作
文章目錄
吐槽
- 我在學習Webpack的時候,我看的視屏是Webpack3.0版本,差不多應該是17年的視屏,而現在是Webpack4.0版本,哎呀我去,那區別是真的大,一起步就摔倒,真的是一步一個坑,步步皆是坑,可見這版本之間相差還是蠻大的。其實我也有想過去看Webpack最新教程,但是想想還是算了,應該只是一點點區別而已,鬼知道步步是坑啊,嗚嗚嗚~ 哭遼 ~,就這樣我不停百度,把坑都填好了,就這樣,我磕磕碰碰的完成了Webpack的學習。當然過程還是學到了很多的。
- 下面就是我根據百度的東西以及自己的見解,寫的一個簡單的Webpack操作。當然小白的我還是借鑑了一些前輩們的經驗,在此謝謝各位前輩們。
概述
前言
我們在開發項目時,會用到很多的靜態資源,我們在瀏覽器,瀏覽網頁時,網頁加載的速度就會變慢,而且有很多的文件都是相互依賴的。
- 總結
- 網頁加載速度慢, 因爲 我們要發起很多的二次請求
- 要處理錯綜複雜的依賴關係
- 如何解決
- 合併、壓縮、精靈圖、圖片的Base64編碼
- requireJS、也可以使用webpack可以解決各個包之間的複雜依賴關係
webpack是什麼呢
webpack 是前端的一個項目構建工具,它是基於 Node.js 開發出來的一個前端工具
- 藉助於webpack這個前端自動化構建工具,可以完美實現資源的合併、打包、壓縮、混淆等諸多功能。
- 下圖:看左邊許多的文件,文件與文件之間又存在關係,經過webpack打包之後,就形成了右邊的樣子,文件少,還無依賴。
- 從圖中我們可以看出,Webpack 可以將多種靜態資源 js、css、less 轉換成一個靜態文件,減少了頁面的請求。
- webpack中文網
Webpack的安裝
- 運行
npm i webpack -g
全局安裝webpack,這樣就能在全局使用webpack的命令 - 在項目根目錄中運行
npm i webpack --save-dev
安裝到項目依賴中
項目初始化
- 創建如下目錄結構
- 初始化項目,會在項目的根目錄下生成一個
package.json
文件npm init -y
- 安裝
webpack
和webpack-cli
(webpack4.0以後需要單獨安裝)
安裝完成後,你會找到npm install webpack webpack-cli --save-dev
node_modules\.bin\webpack
- 查看
package.json
文件
- 編寫
index.js
,簡單寫一句輸出語句即可console.log("ok");
打包測試
-
輸入打包命令
webpack ./src/index.js -o ./dist/bundle.js
在webpack4.0以後,打包命令需要加
-o
,不然回報如下錯誤
-
成功,你會發現 dist 目錄下多了一個
main.js
的文件
-
在
index.html
中引入 dist 目錄下的main.js
文件<script src="../dist/main.js"></script>
-
打開瀏覽器後,運行index.html,
F12
打開控制檯,輸出ok
就行 -
編寫
webpack.config.js
文件const path = require('path'); module.exports = { // 配置入口(要打包的文件) entry: path.join(__dirname, './src/index.js'), // 輸出文件相關配置 output: { // 配置出口,指定打包好的文件存放路徑 path: path.join(__dirname, './dist'), // 要輸出的文件名 filename: 'main.js' }, mode: 'development' }
-
直接輸入
webpack
命令即可 -
你或許會遇見下面的黃色警告
黃色警告:是因爲webpack4引入了模式,有開發模式,生產模式,無這三個狀態
可以看到末尾並沒有生成我們所打包的main.js的信息
黃色部分的警告的意思是,沒有設置模式,有開發模式和生產模式兩種,webpack.config.js
添加屬性:mode: 'development'
樣式的處理
普通CSS處理
- 首先在CSS目錄下新建一個
index.css
文件,寫點樣式body { background-color: green; }
- 在
index.js
文件中,將css引入import './css/index.css';
- 此時我們打包後,會報下面錯誤
You may need an appropriate loader to handle this file type,
currently no loaders are configured to process this file.
它的意思是說:沒有一個合適的加載器 - 這時我們需要安裝第三方
loader
加載器- css-loader:用於處理 css 文件,使得能在 js 文件中引入使用;
- style-loader:用於將 css 文件注入到 index.html 中的
<style>
標籤上; - 安裝命令
npm i style-loader css-loader --save-dev
webpack.config.js
中,配置第三方匹配規則// 配置第三方模塊 module: { // 配置匹配規則 rules: [ { test: /\.css$/, // 匹配以後綴爲.css的文件 use: ['style-loader', 'css-loader'] } ] }
- test: 是一個正則表達式
- use: 對應處理的 loader 插件名稱(處理順序是從右往左)
- 打包測試
- 可以看到樣式已經添加到
<style>
標籤中了,且背景已經綠了
sass處理
- 在 css 目錄中,新建一個
index.scss
文件body { div { width: 250px; height: 250px; border: 2px solid #000; margin: 10px; } #a { font-size: 20px; } #b { color: red; } }
- 在
index.html
中,添加如下<div id="a">aaaaaa</div> <div id="b">bbbbbb</div>
index.js
引入index.scss
文件import './css/index.scss';
- 安裝
node-sass
和sass-loader
npm i node-sass sass-loader --save-dev
webpack.config.js
,配置module.rules匹配規則{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
- 打包測試
- 打開
F12
後,已經成功了
(別問我爲什麼不截效果圖,因爲效果圖…好醜…)
less處理
- 在 css 目錄中,新建一個
index.less
文件body { div { color: #fff; } }
index.js
引入index.less
import './css/index.less';
- 安裝
less
和less-loader
npm i less less-loader --save-dev
webpack.config.js
中,配置module.rules匹配規則{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }
- 打包測試
F12
查看,看得出來,成功了
開啓 SourceMap
- 先註釋掉這些東西
- 在
index.js
中
別懷疑,對,就是console.loo("ok");
console.loo()
,很明顯,這個是一個錯誤的語句。 webpack.config.js
中,開啓 source-mapmodule.exports = { // ... devtool: 'source-map', // 開啓 source-map // ... }
webpack.config.js
中,module.rule 配置如下rules: [ { test: /\.(sc|sa|le|c)ss$/, use: [ "style-loader", { loader: 'css-loader', options: {sourceMap:true} }, { loader: 'sass-loader', options: {sourceMap: true} }, { loader: 'less-loader', options: {sourceMap: true} } ] } ]
- 打包測試,打包信息多了條信息,在
dist
目錄下,多了個main.js.map
文件,這個文件裏面是映射的對應關係
- 可以發現,具體的報錯信息以及定位,一目瞭然
- 來看看CSS的
處理圖片
- 安裝
url-loader
和file-loader
npm i url-loader file-loader --save-dev
webpack.config.js
中,配置module.rulesrules: [ { test: /\.(png|jpg|gif|bmp|jpeg)$/, use: ['url-loader'] } ]
- 給頁面中
#a
添加一張背景圖 - 打包測試
- 查看元素,你會看到一串 Base64 的字符串
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEB ... FFFABRRRQB/9k=
- 關於
url-loader
的一些參數use: ['url-loader?limit=53251&name=[hash:8]-[name].[ext]']
- limit:當圖片大小,大於指定字節數時,就不會轉爲base64字符串
- [hash]: 哈希值,共32位
- [name]: 使用原來名稱
- [ext]: 使用原本後綴
安裝 webpack-dev-server
- 作用:我們每次只要把文件修改一下,就需要進行重新打包,這樣非常麻煩,而
webpack-dev-server
就是爲此誕生的。 - 安裝
npm i webpack-dev-server --save-dev
- 打開
package.json
,配置scripts
,如下
key可以隨意,你可以直接寫成"scripts": { // ... "webpack-dev-server": "webpack-dev-server" // ... },
dev
,我這樣寫,也僅僅只是隨便記住這個單詞,哈哈。 - 運行
npm run webpack-dev-server
- 你會看到這兩條信息
i 「wds」: Project is running at http://localhost:8080/ i 「wds」: webpack output is served from /
- 第一條:項目運行地址
- 第二條:輸出文件的位置在
/
下,也就是項目根目錄下
- 修改
index.js
中的代碼,重新刷新瀏覽器(不用重新打包),也發現沒有任何效果,那是因爲輸出文件被放到項目根目錄下了
修改main.js引入路徑<!-- 開啓 webpack-dev-server 後,輸出文件在 項目根目錄下 --> <script src="../main.js"></script>
- 修改
webpack-dev-server
配置"scripts": { // ... "webpack-dev-server": "webpack-dev-server --open --port 8888 --contentBase src --hot" // ... },
- open:自動打開瀏覽器
- port:修改端口號
- contentBase:指定項目運行根目錄
- hot:啓用熱更新
- 修改完成後,重新打包即可看到效果
webpack-dev-server的第二種配置方式(瞭解)
webpack.config.js
中,module.exports 配置屬性devServer: { open: true, port: 8888, contentBase: 'src', hot: true // 啓用熱更新的第一步 }
- 啓用熱更新第二步,
webpack.config.js
中,頂部引入const webpack = require('webpack');
- 啓用熱更新第三步,
webpack.config.js
中,module.exports配置屬性plugins: [ // 創建熱更新的模板對象 new webpack.HotModuleReplacementPlugin() ]
JavaScript 處理
-
有些時候,我們寫的ES6代碼,瀏覽器並不支持,所以需要將ES6的代碼,轉爲更低級的,瀏覽器可以識別的。
-
index.js
編寫一段ES6代碼class Person { static info = { name: '小靈', age: 17 } } console.log(Person.info);
-
安裝相關包
cnpm i babel-loader @babel/core @babel/preset-env -D cnpm i @babel/plugin-proposal-class-properties -D
-
webpack.config.js
配置如下,配置module.rulesrules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-proposal-class-properties'] } }, exclude: /node_modules/ } ]
options
這一塊可以移到項目根目錄的.babelrc
文件{ "presets": ["@babel/env"], "plugins": ["@babel/proposal-class-properties"] }
-
執行 npm run webpack-dev-server
vue 組件處理
- 安裝
vue-loader
和vue-template-compiler
cnpm i vue vue-loader vue-template-compiler -D
index.js
導入Vueimport Vue from 'vue';
- 因爲導入的Vue,功能不完善,只提供了 runtime-only 的方式,默認是導入
dist/vue.runtime.common.js
的,所以需要修改一下- 直接修改路徑
import Vue from '../node_modules/vue/dist/vue.js'
- 也可以在
webpack.config.js
中添加如下(推薦)module.exports = { // ... resolve: { alias: { "vue$": "vue/dist/vue.js" } } // ... }
- 直接修改路徑
webpack.config.js
中,在vue-loader 15.*
之後,要添加如下const vueLoaderPlugin = require('vue-loader/lib/plugin');
webpack.config.js
中,plugins 配置如下module.exports = { // ... plugins: [ new vueLoaderPlugin() ] // ... }
- 創建
App.vue
組件
注意:在.vue
組件中,只能有<template>
、<script>
、<style>
三樣標籤<template> <h1>App 組件</h1> </template> <script> </script> <style> </style>
webpack.config.js
中,module.rules 配置屬性rules: [ {test: /\.vue/, use: 'vue-loader'} ]
index.html
添加如下<div id="app"></div>
- 導入
index.js
中導入App.vue
組件import App from './js/App.vue';
index.js
中,創建Vue實例對象var vm = new Vue({ el: '#app', render: function(createElements) { return createElements(App); } });
- [Vue warn]: Cannot find element: #app
- 是因爲頁面還沒加載完,所以找不到此元素,我們直接把
<script>
引入放到低端即可
- 是因爲頁面還沒加載完,所以找不到此元素,我們直接把
路由 router
- 安裝
vue-router
cnpm i vue-router -D
index.js
如下import Vue from 'vue'; import VueRouter from 'vue-router' // 手動安裝 VueRouter Vue.use(VueRouter); // 導入 login 組件 import login from './js/login.vue' // 創建路由對象 var router = new VueRouter({ routes: [ {path: '/login', component: login} ] }); var vm = new Vue({ el: '#app', render: els => els(App), router });
export default 和 export
ES6中的導入和導出
- 導入:
- import 模塊名稱 from 模塊標識符
- import 路徑
- 導出:
- export default
- export
- 注意:
- export default 此方式導出,外部可以使用任意變量接收
- export default 同一個模塊中,只允許導出一次
- export 此方式導出,外部必須嚴格按照導出的指定的變量名接收
- export 外部使用 { 導出的變量名, … } 的形式接收
- export 外部可以設置別名:{ 導出的變量名 as 別名, … }
Node的導入和導出
- 導入:
- var 名稱 = require(模塊標識符)
- 導出:
- module.exports
- exports
組件中style標籤的 lang 屬性 和 scope 屬性
- lang:指定CSS的語言,可以是sacc,scss,less等
- scope:不寫,則默認樣式爲全局,反之則局部,它的原理是利用屬性選擇器
html-webpack-plugin 插件
- 安裝
cnpm i html-webpack-plugin -D
webpack.config.js
引入const htmlWebpackPlugin = require('html-webpack-plugin');
webpack.config.js
,module.plugins配置如下plugins: [ // 在內存中生成一個 HTML 插件 new htmlWebpackPlugin({ // 指定模板頁面 template: path.join(__dirname, './src/index.html'), // 指定生成的文件名 filename: 'index.html' }) ],
- 打包測試之後,在瀏覽器中,控制檯中,會發現有以
VM
開頭的文件
雜七雜八
本篇源碼
鏈接:https://pan.baidu.com/s/19nKuINk3C_-f3lfpRRUyrw
提取碼:y158
import找包的規則:
- 找項目根目錄中有沒有node_modules的文件夾
- 在node_modules 中根據包名,找對應的文件夾
- 在文件夾中,找到一個叫做 package.json 的包配置文件
- 在package.json中,找到main屬性,屬性值是這個包在被加載時的入口文件