vue?webpack打包原理解析(全網(wǎng)最新最全)
一、前端模塊化
webpack是讓我們可以進(jìn)行模塊化開(kāi)發(fā),并且會(huì)幫助我們處理模塊間的依賴關(guān)系。
并且不僅僅是JavaScript文件,還有CSS、圖片、json文件等等,在webpack中都可以被當(dāng)做模塊來(lái)使用。
二、打包
webpack中的各種資源模塊進(jìn)行打包合并成一個(gè)或多個(gè)包(Bundle)。
在打包的過(guò)程中,還可以對(duì)資源進(jìn)行處理,比如壓縮圖片,將scss轉(zhuǎn)成css,將ES6語(yǔ)法轉(zhuǎn)成ES5語(yǔ)法,將TypeScript轉(zhuǎn)成JavaScript等等操作。
和gulp的有什么區(qū)別?
- gulp叫做前端自動(dòng)化任務(wù)管理工具;
- gulp會(huì)定義一系列的task,處理各種事務(wù)(ES6、ts轉(zhuǎn)化、圖片壓縮、scss轉(zhuǎn)成css)
- 通過(guò)gulp依次執(zhí)行這些task,并且讓整個(gè)流程自動(dòng)化;
const gulp = require('gulp')
const babel = require('gulp-babel')
gulp.task('js',() =>
gulp.src('src/*.js')
.pipe(babel({
prests:['es2015']
}))
.pipe(gulp.dest('dist'))
);什么時(shí)候使用gulp呢?
- 如果工程模塊依賴比較簡(jiǎn)單,甚至沒(méi)有用到模塊化的概念;
- 只需要進(jìn)行簡(jiǎn)單的合并、壓縮;
總而言之,webpack是功能更加強(qiáng)大的gulp。
三、安裝webpack
1、安裝node.js
打開(kāi)官網(wǎng)下載鏈接:Download | Node.js 我這里下載的是node-v6.9.2-x64.msi,如下圖:

2、安裝webpack
npm install webpack@3.6.0 -g

四、webpack打包js
1、普通打包方式
webpack .\src\main.js .\dist\bundle.js
打包之后,就可以在index.html中引入bundle.js了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="./dist/bundle.js"></script> </body> </html>
2、webpack.config.js配置和package.json配置
(1)webpack.config.js
const path = require('path')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
}(2)package.json
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.6.0"
}
}3、理解開(kāi)發(fā)時(shí)依賴和運(yùn)行時(shí)依賴
本地安裝webpack
npm install webpack@3.6.0 --save-dev

在終端中敲的命令,運(yùn)用的都是全局的webpack。
五、loader
1、loader簡(jiǎn)介
loader 用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換。loader 可以使你在 import 或"加載"模塊時(shí)預(yù)處理文件。因此,loader 類似于其他構(gòu)建工具中“任務(wù)(task)”,并提供了處理前端構(gòu)建步驟的強(qiáng)大方法。loader 可以將文件從不同的語(yǔ)言(如 TypeScript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!
你可以使用 loader 告訴 webpack 加載 CSS 文件,或者將 TypeScript 轉(zhuǎn)為 JavaScript。為此,首先安裝相對(duì)應(yīng)的 loader:
npm install --save-dev css-loader npm install --save-dev ts-loader
然后指示 webpack 對(duì)每個(gè) .css 使用 css-loader,以及對(duì)所有 .ts 文件使用 ts-loader:
webpack.config.js
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};2、使用 loader
在你的應(yīng)用程序中,有三種使用 loader 的方式:
- 配置(推薦):在 webpack.config.js 文件中指定 loader。
- 內(nèi)聯(lián):在每個(gè)
import語(yǔ)句中顯式指定 loader。 - CLI:在 shell 命令中指定它們。
3、配置[Configuration]允許你在 webpack 配置中指定多個(gè) loader
這是展示 loader 的一種簡(jiǎn)明方式,并且有助于使代碼變得簡(jiǎn)潔。同時(shí)讓你對(duì)各個(gè) loader 有個(gè)全局概覽:
六、less與url-loader
1、安裝less
npm install --save-dev less-loader less

2、less示例
將 css-loader、style-loader 和 less-loader 鏈?zhǔn)秸{(diào)用,可以把所有樣式立即應(yīng)用于 DOM。
module.exports = {
...
module: {
rules: [{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}]
}
};
module.exports = {
...
module: {
rules: [{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}]
}
};3、安裝url-loader
npm install --save-dev url-loader

4、url-loader用法
url-loader 功能類似于 file-loader,但是在文件大?。▎挝?byte)低于指定的限制時(shí),可以返回一個(gè) DataURL。
import img from './image.png'
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}當(dāng)圖片大小大于limit中限制時(shí),需要使用file-loader進(jìn)行圖片加載,再轉(zhuǎn)為base64字符串。
5、file-loader
1、安裝file-loader
npm install --save-dev file-loader

七、加載圖片代碼實(shí)例
1、項(xiàng)目目錄

2、index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="./dist/bundle.js"></script> </body> </html>
3、main.js
// 1.使用commonjs的模塊化規(guī)范
const {add, mul} = require('./js/mathUtils.js')
console.log(add(20, 30));
console.log(mul(20, 30));
// 2.使用ES6的模塊化的規(guī)范
import {name, age, height} from "./js/info";
console.log(name);
console.log(age);
console.log(height);
// 3.依賴css文件
require('./css/normal.css')
// 4.依賴less文件
require('./css/special.less')
document.writeln('<h2>你好啊,哪吒!</h2>')4、info.js
export const name = 'why'; export const age = 18; export const height = 1.88;
5、mathUtils.js
export const name = 'why'; export const age = 18; export const height = 1.88;
6、normal.css
body {
/*background-color: red;*/
background: url("../img/timg.jpg");
}7、special.less
@fontSize: 50px;
@fontColor: orange;
body {
font-size: @fontSize;
color: @fontColor;
}八、ES6語(yǔ)法處理
webpack打包的js文件,并沒(méi)有將ES6語(yǔ)法轉(zhuǎn)譯成ES5的語(yǔ)法,因此可能對(duì)某些瀏覽器不兼容,此時(shí)需要使用babel。
1、安裝babel-loader
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
2、在 webpack 配置對(duì)象中,需要添加 babel-loader 到 module 的 loaders 列表中,
像下面這樣:
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]
}bundle.js從ES6語(yǔ)法編譯為ES5語(yǔ)法了。
九、webpack使用vue的配置過(guò)程
1、安裝vue的三種方式 直接下載應(yīng)用CDN引入npm安裝
2、npm安裝vue
因?yàn)椴皇沁\(yùn)行時(shí)依賴,以后部署的時(shí)候也要使用vue,所以不需要-vue
npm install vue --save
runtime-only -> 代碼中,不可以有任何的template
runtime-compiler -> 代碼中可以有template,因?yàn)橛衏ompiler可以用于編譯template
使用如下配置解決找不到template的報(bào)錯(cuò)問(wèn)題:
resolve: {
? ? // alias: 別名
? ? extensions: ['.js', '.css', '.vue'],
? ? alias: {
? ? ? 'vue$': 'vue/dist/vue.esm.js'
? ? }
? }十、el和template區(qū)別
1、正常運(yùn)行之后,我們要考慮一個(gè)問(wèn)題
如果我們將data中的數(shù)據(jù)顯示在界面中,就必須修改index.html;
如果我們后面自定義了組件,也必須修改index.html來(lái)使用組件;
但是html模板在之后的開(kāi)發(fā)中,并不希望手動(dòng)的頻繁的修改index.html;
2、解決方法 --> 定義template屬性
在前面的Vue實(shí)例中,我們定義了el屬性,用于和index.html中的#app進(jìn)行綁定,讓Vue實(shí)例之后可以管理它其中的內(nèi)容;
這里我們可以將div元素中的{{message}}內(nèi)容刪掉,只保留一個(gè)基本的id為div的元素;
但是如果我們依然希望在其中顯示{{message}}的內(nèi)容,我們可以定義一個(gè)template屬性;
如果el和template同時(shí)存在時(shí),template會(huì)替換掉el的內(nèi)容:
new Vue({
el:'#app',
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
<h2>{{name}}</h2>
</div>
`,
data:{
message:'hello webpack',
name:'哪吒'
},
methods:{
btnClick(){
console.log('i am csdn 哪吒!')
}
}
})簡(jiǎn)化:
const App = {
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
<h2>{{name}}</h2>
</div>
`,
data:{
return {
message:'hello webpack',
name:'哪吒'
}
},
methods:{
btnClick(){
console.log('i am csdn 哪吒!')
}
}
}
new Vue({
el:'#app',
template:`<App/>`,
components:{
App
}
})再次簡(jiǎn)化:
app.js
export default {
template: `
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按鈕</button>
<h2>{{name}}</h2>
</div>
`,
data() {
return {
message: 'Hello Webpack',
name: 'coderwhy'
}
},
methods: {
btnClick() {
}
}
}main.js
// 5.使用Vue進(jìn)行開(kāi)發(fā)
import Vue from 'vue'
import App from './vue/app'
new Vue({
el: '#app',
template: '<App/>',
components: {
App
}
})終極優(yōu)化
App.vue
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">按鈕</button>
<h2>{{name}}</h2>
<Cpn/>
</div>
</template>
<script>
import Cpn from './Cpn'
export default {
name: "App",
components: {
Cpn
},
data() {
return {
message: 'Hello Webpack',
name: 'coderwhy'
}
},
methods: {
btnClick() {
}
}
}
</script>
<style scoped>
.title {
color: green;
}
</style>
main.js
// 5.使用Vue進(jìn)行開(kāi)發(fā)
import Vue from 'vue'
import App from './vue/App.vue'
new Vue({
el: '#app',
template: '<App/>',
components: {
App
}
})但是,此時(shí)程序無(wú)法加載vue文件,需要npm安裝loader
npm install vue-loader vue-template-compiler --save-dev
webpack.config.js中配置:
...
{
test: /\.vue$/,
use: ['vue-loader']
}
...十一、認(rèn)識(shí)plugin
1、plugin是什么?
plugin是插件的意思,通常適用于對(duì)某個(gè)現(xiàn)有的框架的擴(kuò)展。
webpack中的插件,就是對(duì)webpack現(xiàn)有功能的各種擴(kuò)展,比如打包優(yōu)化,文件壓縮等。
2、loader和plugin的區(qū)別?
loader主要用于轉(zhuǎn)換某些類型的模板,它是一個(gè)轉(zhuǎn)換器。
plugin是插件,它是對(duì)webpack本身的擴(kuò)展,是一個(gè)擴(kuò)展器。
3、plugin的使用過(guò)程 通過(guò)npm安裝需要使用的plugins在webpack.config.js中的plugins中配置插件
4、代碼實(shí)例
plugins: [
new webpack.BannerPlugin('最終版權(quán)歸aaa所有'),
],5、htmlWebpackPlugin
(1)、作用
自動(dòng)生成一個(gè)index.html文件將打包的js文件,自動(dòng)通過(guò)script標(biāo)簽插入到body中
(2)安裝htmlWebpackPlugin
npm install htnl-webpack-plugin --save-dev
(3)使用插件
修改webpack.config.js文件中plugins部分的內(nèi)容
plugins: [
new webpack.BannerPlugin('最終版權(quán)歸aaa所有'),
new HtmlWebpackPlugin({
template: 'index.html'
})
],6、第三方插件uglifyjs-webpack-plugin
指定版本1.1.1,和CLI2保持一致。
(1)安裝
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
(2)修改配置文件
plugins: [
new webpack.BannerPlugin('最終版權(quán)歸aaa所有'),
new HtmlWebpackPlugin({
template: 'index.html'
}),
new UglifyjsWebpackPlugin()
],7、webpack-dev-server搭建本地服務(wù)器
(1)webpack-dev-server簡(jiǎn)介
webpack提供了一個(gè)可選的本地開(kāi)發(fā)服務(wù)器,這個(gè)本地服務(wù)器基于node.js搭建,內(nèi)部使用express框架,可以實(shí)現(xiàn)我們想要的讓瀏覽器自動(dòng)刷新顯示我們修改后的結(jié)果。
(2)安裝
npm install --save-dev webpack-dev-server@2.9.1
(3)屬性介紹
devserver作為webpack的一個(gè)選項(xiàng),選項(xiàng)本身可以設(shè)置如下屬性:
contentBase:為哪一個(gè)文件夾提供本地服務(wù),默認(rèn)是根文件夾,我們這里要填寫(xiě)./distport:端口號(hào)inline:頁(yè)面實(shí)時(shí)刷新historyApiFallback:在SPA頁(yè)面中,依賴HTML5的history模式
(4)配置實(shí)例
devServer: {
contentBase: './dist',
inline: true
}8、webpack配置文件的分離
(1)安裝插件
npm install webpack-merge --save-dev
(2)分離代碼實(shí)例
webpack-config.js
const path = require('path')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.css$/,
// css-loader只負(fù)責(zé)將css文件進(jìn)行加載
// style-loader負(fù)責(zé)將樣式添加到DOM中
// 使用多個(gè)loader時(shí), 是從右向左
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader", // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader", // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
// 當(dāng)加載的圖片, 小于limit時(shí), 會(huì)將圖片編譯成base64字符串形式.
// 當(dāng)加載的圖片, 大于limit時(shí), 需要使用file-loader模塊進(jìn)行加載.
limit: 13000,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
// alias: 別名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
build/base.config.js
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'bundle.js',
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /\.css$/,
// css-loader只負(fù)責(zé)將css文件進(jìn)行加載
// style-loader負(fù)責(zé)將樣式添加到DOM中
// 使用多個(gè)loader時(shí), 是從右向左
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.less$/,
use: [{
loader: "style-loader", // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader", // compiles Less to CSS
}]
},
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
// 當(dāng)加載的圖片, 小于limit時(shí), 會(huì)將圖片編譯成base64字符串形式.
// 當(dāng)加載的圖片, 大于limit時(shí), 需要使用file-loader模塊進(jìn)行加載.
limit: 13000,
name: 'img/[name].[hash:8].[ext]'
},
}
]
},
{
test: /\.js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
resolve: {
// alias: 別名
extensions: ['.js', '.css', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new webpack.BannerPlugin('最終版權(quán)歸aaa所有'),
new HtmlWebpackPlugin({
template: 'index.html'
})
]
}
build/dev.config.js
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig, {
devServer: {
contentBase: './dist',
inline: true
}
})build/prod.config.js
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig, {
plugins: [
new UglifyjsWebpackPlugin()
]
})更改package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
}到此這篇關(guān)于vue webpack打包原理的文章就介紹到這了,更多相關(guān)vue webpack打包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3使用defineModel實(shí)現(xiàn)父子組件雙向綁定
這篇文章主要個(gè)給大家介紹了在vue3中使用defineModel進(jìn)行父子組件中的雙向綁定,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01
Vue實(shí)現(xiàn)圖片輪播組件思路及實(shí)例解析
這篇文章主要介紹了Vue實(shí)現(xiàn)圖片輪播組件思路及實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Vue3+vueuse實(shí)現(xiàn)放大鏡示例詳解
這篇文章主要為大家介紹了Vue3+vueuse實(shí)現(xiàn)放大鏡示例過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
vue elementui 實(shí)現(xiàn)搜索欄公共組件封裝的實(shí)例代碼
這篇文章主要介紹了vue elementui 搜索欄公共組件封裝,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
五步教你用Nginx部署Vue項(xiàng)目及解決動(dòng)態(tài)路由刷新404問(wèn)題
nginx 是一個(gè)代理的服務(wù)器,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)五步教你用Nginx部署Vue項(xiàng)目及解決動(dòng)態(tài)路由刷新404問(wèn)題的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
VuePress 靜態(tài)網(wǎng)站生成方法步驟
這篇文章主要介紹了VuePress 靜態(tài)網(wǎng)站生成方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
vue項(xiàng)目實(shí)戰(zhàn)之圓柱狀水波效果實(shí)現(xiàn)
最近工作中實(shí)現(xiàn)的一個(gè)效果不錯(cuò),分享給大家,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目實(shí)戰(zhàn)之圓柱狀水波效果實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
vue項(xiàng)目中使用rem替換px的實(shí)現(xiàn)示例
移動(dòng)端頁(yè)面適配,rem和vw適配方案,本文主要介紹了vue項(xiàng)目中使用rem替換px的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07

