webpack、Vue

目錄

一、起步

    1、安裝    2、基本使用    3、創建bundle文件    4、使用配置文件

二、開發

    1、webpack-dev-server自動打包編譯    2、html-webpack-plugin自動添加js入口文件

三、管理資源

    1、加載CSS、less、scss    2、加載圖片    3、加載字體

四、bable處理高級js語法

五、Vue

    1、開發環境    2、完整版     3、運行時    4、vue-router    5、vue-resource    6、vuex

網頁中常見的靜態資源:JS(.js  .jsx  .coffee  .ts)、CSS(.css  .less  .sass  .scss)、Images(.jpg  .png  .gif  .bmp  .svg)、字體文件Fonts(.svg  .ttf  .eot  .woff  .woff2)、模板文件(.ejs  .jade  .vue)。靜態資源使網頁加載速度慢,因爲要發起很多二次請求;靜態資源間存在綜複雜的依賴關係。解決辦法:合併壓縮(sprite、圖片的Base64編碼等)、解決各個包之間複雜的依賴關係。

webpack是基於Node.js開發的前端項目構建工具。本質上,webpack是一個現代JavaScript應用程序的靜態模塊打包器(module bundler)。當webpack處理應用程序時,會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序需要的每個模塊,然後將所有模塊打包成一個或多個bundle。官網:https://webpack.github.io/  https://www.webpackjs.com/

Gulp是基於task任務的,webpack是基於整個項目進行構建的。

一、起步

1、安裝

確保已安裝Node.js最新的長期支持版本(LTS),因爲使用舊版本可能遇到各種問題,可能缺少webpack功能以及/或者缺少相關package包。

包安裝出錯時,可刪除node_modules文件夾,運行npm install重新安裝所有包。也可以npm uninstall <包名>卸載相應的包。

(1)全局安裝

運行npm i webpack -g全局安裝。

(2)本地安裝

對於大多數項目,建議本地安裝(先全局安裝,才能使用webpack命令)。使引入破壞式變更(breaking change)的依賴時,更容易分別升級項目。在項目根目錄中運行以下命令安裝到項目依賴中。

安裝到最新版本:npm install --save-dev webpack
安裝到特定版本:npm install --save-dev webpack@<version>

使用webpack 4+版本時,還需要安裝CLI:npm install --save-dev webpack-cli,提供命令行(如webpack命令)和打包功能。

2、基本使用

webpack-demo         // 根目錄
  |- package.json
  |- webpack.config.js // 配置文件
  |- /dist             // 發佈的文件
    |- index.html        // 首頁
    |- bundle.js
  |- /src              // 源代碼
    |- /css
    |- /js
    |- /images
    |- main.js           // js入口文件
  |- /node_modules

創建項目基本的目錄結構;運行npm init -y在根目錄下創建package.json(項目是中文名使用npm init),使用npm管理項目中的依賴包;運行npm install webpack webpack-cli --save-dev本地安裝webpack。

使用npm i jquery -S安裝jquery類庫。import $ from 'jquery'導入jquery類庫。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>起步</title>
</head>
<body>
    <ul>
      <li>這是第1個li</li>
      <li>這是第2個li</li>
      <li>這是第3個li</li>
      <li>這是第4個li</li>
    </ul>
    <script src="./bundle.js"></script>
</body>
</html>
/* main.js */
import $ from 'jquery' // 相當於node中,const $=require('jquery')

$(function(){
  // 設置背景色隔行變色
  $('li:odd').css('backgroundColor','pink');
  $('li:even').css('backgroundColor','#ddd');
})

import或require導入包的查找規則:項目根目錄中node_modules文件夾->根據包名找對應的文件夾->package.json包配置文件->main屬性,指定了該包在被加載時的入口文件。

3、創建bundle文件

“源”代碼(/src)是用於書寫和編輯的代碼,“分發”代碼(/dist)是構建過程產生的代碼最小化和優化後的“輸出”目錄,最終將在瀏覽器中加載。

webpack能夠很好地支持import和export語句、及多種其它模塊語法。webpack會將代碼“轉譯”,以便舊版本瀏覽器可以執行。

將src/main.js“轉譯”爲dist/bundle.js:webpack .\src\main.js --output .\dist\bundle.js(入口文件路徑 輸出文件路徑);或npx webpack,將腳本作爲入口起點,然後輸出爲main.js。

4、使用配置文件

在webpack 4中,可以無須任何配置使用,然而大多數項目會需要很複雜的設置,webpack仍然要支持配置文件,這比在終端中手動輸入大量命令要高效的多,所以讓我們創建一個取代以上使用CLI選項方式的配置文件。

使用配置文件創建bundle:webpacknpx webpack --config webpack.config.js。在控制檯直接輸入webpack命令執行時,去項目根目錄查找配置文件,解析得到導出的配置對象,拿到配置對象中指定的入口和出口,進行打包構建。webpack 4有約定,爲了儘量減少配置文件的體積,默認約定了打包的入口是./src/index.js和打包的出口是./dist/main.js。

/* webpack.config.js */
const path=require('path')

module.exports={ // node語法
  entry:'./src/main.js', // 項目入口文件,默認爲'./src/index.js'
  output:{
    filename:'bundle.js', // 輸出的路徑
    path:path.resolve(__dirname,'dist') // 輸出的文件名
  }
}

導入包是,省略.jsx等後綴名;配置和使用@路徑符號。

// webpack.config.js
module.exports={
  resolve:{
    extensions:['.js','.jsx','.json'], // 這幾個文件後綴名可省略不寫
    alias:{ // 別名
      '@':path.join(__dirname,'./src')
    }
  }
}

// index.js
import Welcome from '@/components/Welcome' // 省略了.jsx

二、開發

1、webpack-dev-server自動打包編譯

使用webpack-dev-server工具實現代碼自動打包編譯,修改和保存任意源文件,web服務器就會自動重新加載編譯後的代碼。

(1)運行npm install --save-dev webpack-dev-server將該工具安裝到項目的本地開發依賴。該工具依賴於webpack,在本地項目中必須安裝webpack。

(2)在命令行直接運行webpack-dev-server命令進行打包,報錯,因爲webpack-dev-server是本地安裝的,無法把它當作腳本命令。需要藉助於package.json文件中的指令運行webpack-dev-server命令。在scripts節點下新增"dev": "webpack-dev-server"指令,運行npm run dev。或者新增"start": "webpack-dev-server --open --port 3000 --concentBase dist --hot",運行npm start打開服務器。

(3)命令參數

方式一:修改package.json的script節點

--open 自動在瀏覽器中打開該端口地址,後面可跟瀏覽器名稱,如firefox
--port 修改運行時的端口號
--host 修改運行時的域名,如127.0.0.1
--contentBase 設置託管的根目錄,在瀏覽器中直接打開該路徑下的.html文件
--hot 啓動瀏覽器熱更新,不會重新生成bundle.js,只會生成一個.js和.json補丁保存局部更新的代碼,並實現瀏覽器的無重載異步刷新(對css等有效果,對js無效果)

方式二:修改webpack.config.js文件,新增devServer節點

/* webpack.config.js */
const path=require('path')
const webpack=require('webpack') // 啓用熱更新使用

module.exports={
  devServer:{
    open:true,
    port:3000,
    contentBase:'./dist',
    hot:true
  },
  plugins:[
    new webpack.HotModuleReplacementPlugin() // 放置熱更新的模塊對象
  ]
}

(4)webpack-dev-server打包生成的bundle.js文件,在項目根目錄<script src="/bundle.js"></script>。並沒有存放到實際的物理磁盤上,而是直接託管到電腦的內存中,在根目錄找不到。由於需要實時打包編譯,放在內存中速度會非常快。

2、html-webpack-plugin自動添加js入口文件

html-webpack-plugin,自動根據指定頁面在內存中生成一個新頁面之後,所有的打包好的bundle會自動添加到新頁面的body底部。不再需要指定啓動目錄和手動處理bundle.js的引用路徑。

npm install --save-dev html-webpack-plugin

/* webpack.config.js */
const path=require('path')
const htmlWebpackPlugin=require('html-webpack-plugin')

module.exports={
  plugins:[ // 配置插件的節點
    new htmlWebpackPlugin({
      template:path.join(__dirname,'./dist/index.html'), // 指定模板頁面
      filename:'index.html', // 指定生成頁面名稱,瀏覽器默認打開index.html
      title:'Output Management'
    })
  ]
}

三、管理資源

webpack默認只能打包處理JS類型的文件,如需引入任何其它類型的文件,需通過loader 。

webpack處理第三方文件類型的過程:發現要處理的文件不是JS文件,去配置文件中查找有沒有對應的第三方loader規則;如果有,調用對應的loader處理這種文件類型,從後往前調用;處理完畢,把處理的結果交給webpack進行打包合併,輸出到bundle.js。

1、加載CSS、less、scss

爲了從JS模塊中import一個CSS文件,需要在module配置中安裝並添加style-loader和css-loader。

/* main.js */
import './css/index.css'
import './css/index.less'
import './css/index.scss'

npm install --save-dev style-loader css-loader

npm install --save-dev less less-loader less是less-loader內部依賴,不需要顯式定義

npm install --save-dev node-sass sass-loader node-sass是sass-loader內部依賴,不需要顯式定義

/* webpack.config.js */
module.exports={
  module:{ // 配置所有第三方模塊的加載器
    rules:[ // 所有第三方模塊的匹配規則
      {test:/\.css$/,use:['style-loader','css-loader']}, // 加載.css文件,從後往前調用
      {test:/\.less$/,use:['style-loader','css-loader','less-loader']}, // 加載.less文件
      {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}, // 加載.scss文件
    ]
  }
}

2、加載圖片

file-loader和url-loader可以接收並加載任何文件。

npm install --save-dev file-loader 使用file-loader,圖片不會被編碼爲base64

npm install --save-dev url-loader file-loader是url-loader內部依賴,不需要顯式定義

{test:/\.(png|svg|jpg|gif)$/,use:'file-loader'}, // 處理圖片
{test:/\.(jpg|png|gif|bmp|jpeg)$/,use:'url-loader?limit=7631&name=[hash:8]-[name].[ext]'}

limit給定的值是圖片的大小(byte),如果圖片大於等於給定的limit值,則不會被轉爲base64格式的字符串。

圖片名默認會被修改爲哈希值,防止重名衝突。name=[name].[ext]使圖片保持原名,在前面加哈希值解決重名衝突。

3、加載字體

npm install --save-dev file-loader url-loader

{test:/\.(ttf|eot|svg|woff|woff2)$/,use:'url-loader'} // 處理字體文件

四、bable處理高級js語法

webpack默認只能處理部分ES6語法,一些更高級的ES6或ES7語法,需要藉助第三方的loader處理,轉爲低級的語法後,把結果交給webpack打包到bundle.js中。

webpack 4.x | babel-loader 8.x | babel 7.x
npm install -D babel-loader @babel/core @babel/preset-env webpack

npm install -D @babel/runtime @babel/plugin-transform-runtime @babel-runtime是依賴

babel-preset-env是較新的ES語法。(使用了static關鍵字報錯,可能是因爲這只是提案,目前不支持)

babel對一些公共方法使用了非常小的輔助代碼,如_extend。默認情況下會被添加到每一個需要它的文件中,引入babel runtime作爲一個獨立模塊,來避免重複引入。禁用babel自動對每個文件的runtime注入,而是引入babel-plugin-transform-runtime使所有輔助代碼從這裏引用。

配置babel的loader規則時,必須把node_modules目錄排除。否則,babel會把node_modules中所有的第三方JS文件都打包編譯,打包速度非常慢且非常消耗CPU,且即使編譯完畢項目也無法正常運行。

/* webpack.config.js */
module.exports={
  module:{
    rules:[
      {test:/\.js$/,use:'babel-loader',exclude:/node_modules/} // 配置babel處理ES6等高級語法
    ]
  }
}

在項目的根目錄中,新建一個.babelrc的babel配置文件,該文件是JSON格式,不能寫註釋,字符串必須用雙引號。preset預設,可翻譯爲語法。

{
  "presets":["@babel/preset-env"],
  "plugins":["@babel/plugin-transform-runtime"]
}

babel默認啓用嚴格模式,如果要移除嚴格模式,npm install babel-plugin-transform-remove-strict-mode,並修改.babelrc。

{
  "plugins":["transform-remove-strict-mode"]
}

五、Vue

1、開發環境

開發環境下,Vue會提供很多警告來對付常見的錯誤與陷阱。當使用webpack構建工具時,Vue源碼會根據process.env.NODE_ENV決定是否啓用開發環境模式。

/* webpack.config.js */
// webpack 4+
module.exports={
  mode:'development'
}
// webpack 3及其更低版本
var webpack=require('webpack')

module.exports={
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV':JSON.stringify('production')
    })
  ]
}

2、完整版

npm install --save-dev vue

使用import Vue from 'vue'導入Vue構造函數時,"main": "dist/vue.runtime.common.js",只提供了runtime-only的方式。如果需要在客戶端編譯模板(如傳入一個字符串給template選項,或掛載到一個元素上並以其DOM內部的HTML作爲模板),就需要加上編譯器,即完整版。否則會報錯[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

方式1:

/* main.js */
import Vue from '../node_modules/vue/dist/vue.js'

方式2:每次需要重新啓動服務器

/* main.js */
import Vue from 'vue'
/* webpack.config.js */
module.exports={
  resolve:{
    alias:{
      "vue$":"vue/dist/vue.esm.js" // 設置Vue被導入包時的路徑
    }
  }
}

3、運行時

運行時版本相比完整版體積要小大約30%,所以應該儘可能使用這個版本。

npm install --save-dev vue

npm install --save-dev vue-loader vue-template-compiler vue-template-compiler是依賴

/* main.js */
import Vue from 'vue'
import login from './login.vue' // 導入login組件
new Vue({
  el:'#app',
  render:function(createElement){
    return createElement(login)
  }
  // 簡寫爲render:c=>c(login)
})
/* webpack.config.js */
const VueLoaderPlugin=require('vue-loader/lib/plugin')
module.exports={
  module:{
    rules:[
      {test:/\.vue$/,use:'vue-loader'} // 配置.vue文件
    ]
  },
  plugins:[
    new VueLoaderPlugin()
  ]
}

4、vue-router

npm install --save-dev vue

npm install --save-dev vue-router

如果在一個模塊化工程中使用它,必須通過Vue.use()明確地安裝路由功能。

/* main.js */
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

import app from './app.vue'
import router from './router.js'

new Vue({
  el:'#app',
  render:c=>c(app),
  router
})

將<router-link>和<router-view>放到render渲染的<template>中。

/* app.vue */
<template>
  <div>
    <p>render渲染的組件</p>
    <router-link to="/foo">To Foo</router-link>
    <router-link to="/bar">To Foo</router-link>

    <router-view></router-view>
  </div>
</template>

將定義、註冊路由抽離爲router.js

​/* router.js */
import VueRouter from 'vue-router'

import foo from './main/Foo.vue'
import bar from './main/Bar.vue'

var router=new VueRouter({
  routes:[
    {path:'/foo',component:foo},
    {path:'/bar',component:bar}
  ]
})

export default router // 向外暴露router對象

5、vue-resource

npm install --save-dev vue

npm install --save-dev vue-resource

/* main.js */
import Vue from 'vue'
import VueResource from 'vue-resource'

Vue.use(VueResource)

6、vuex

npm install --save-dev vue

npm install vuex --save

npm install es6-promise --save Vuex依賴Promise,如果瀏覽器並沒有實現Promise(如IE)

/* main.js */
import Vue from 'vue'
// import 'es6-promise/auto'
import Vuex from 'vuex'

Vue.use(Vuex)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章