webpack4.x從基礎 到 實戰搭建Vue-Cli

 

 

引言

WebPack的火爆程度已經持續幾年了,無論是Vue-Cli仍是React-Cli又或者是Angular-Cli都是基於Webpack進行搭建的打包系統,早在幾年前就已經出現了一個新的職業WebPack工程師,即使是我不打算從事專業的Webpack,可是咱們也決不能僅限於使用Vue-Cli或其它腳手架工具,並且咱們再實際開發中都得針對本身的項目二次開發腳手架工具,或本身搭建,所以咱們不能只是知其然,也得知其因此然......下面我會把我對webpack的理解根你們分享一下,本文純屬我的理解,有哪裏不對的地方還請評論中或關注同窗們聽我說公衆號留言指出,你們一塊兒學習共同進步。css

爲何要學Webpack?

  • 現今的不少網頁其實能夠看作是功能豐富的應用,它們擁有着複雜的JavaScript代碼和一大堆依賴包。爲了簡化開發的複雜度
  • TS 轉 JS
  • sass 轉 css
  • ES6 轉 ES5
  • 這些改進確實大大的提升了咱們的開發效率,可是利用它們開發的文件每每須要進行額外的處理才能讓瀏覽器識別,而手動處理又是很是繁瑣的,這就爲WebPack類的工具的出現提供了需求

什麼是Webpack?

  • WebPack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊它會構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其轉換和打包爲合適的格式供瀏覽器使用。

webpack和gulp及grunt的對比

其實Webpack和另外兩個並無太多的可比性,Gulp/Grunt是一種可以優化前端的開發流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優勢使得Webpack在不少場景下能夠替代Gulp/Grunt類的工具。html

Grunt和Gulp的工做方式是:在一個配置文件中,指明對某些文件進行相似編譯,組合,壓縮等任務的具體步驟,用了gulp或grunt工具以後能夠自動替你完成這些任務。前端

定義 第一個ES6轉ES5 的 任務
一、 原材料 - *.js
二、加工 - ES6轉ES5插件(babel)
三、出廠 - 生成了ES5
定義 第二個任務 - sass轉CSS 任務
一、 原材料 - *.scss
二、加工 - scss轉css插件
三、出廠 - 生成了瀏覽器可識別的css
以此類推,根據需求配置任務,按照順序執行,第3、4、五..... 任務......,能夠理解爲解放雙手的智能化的工做流程。

 

  • Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個(或多個)瀏覽器可識別的JavaScript文件。vue

webpack是把整個項目中的全部模塊資源,經過入口文件根據import/require分析依賴關係,生成關係樹,而後藉助於loaderplugins兩個核心的屬性及其餘,轉換成瀏覽器能夠識別的JS文件。它不針對流程,而是模塊。node

特色

Webpack 有兩種組織模塊依賴的方式,同步和異步。異步依賴做爲分割點,造成一個新的塊。在優化了依賴樹後,每個異步區塊都做爲一個文件被打包。* Webpack 自己只能處理原生的 JavaScript 模塊,可是 loader 轉換器能夠將各類類型的資源轉換成 JavaScript 模塊。這樣,任何資源均可以成爲 Webpack 能夠處理的模塊。* Webpack 有一個智能解析器,幾乎能夠處理任何第三方庫,不管它們的模塊形式是 CommonJS、 AMD 仍是普通的 JS 文件。甚至在加載依賴的時候,容許使用動態表達式 require(「./templates/」 + name + 「.jade」)。* Webpack 還有一個功能豐富的插件系統。大多數內容功能都是基於這個插件系統運行的,還能夠開發和使用開源的 Webpack 插件,來知足各式各樣的需求。* Webpack 使用異步 I/O 和多級緩存提升運行效率,這使得 Webpack 可以以使人難以置信的速度快速增量編譯。react

核心概念

entry - 入口
  • 指示 webpack 應該使用哪一個模塊,來做爲構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的webpack

entry: {
        index: './src/index.js'
    },
output - 出口
  • output 屬性告訴 webpack 在哪裏輸出它所建立的 bundles,以及如何命名這些文件,默認值爲 ./dist。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你能夠經過在配置中指定一個 output 字段,來配置這些處理過程web

    output: {
            filename: '[name].bundle.[hash].js',
            path: path.join(__dirname, 'dist')
        },
loader
  • loader讓 webpack 可以去處理那些非 JavaScript 文件vue-router

  • loader 能夠將全部類型的文件轉換爲 webpack 可以處理的有效模塊,而後你就能夠利用 webpack 的打包能力,對它們進行處理,本質上,webpack loader 將全部類型的文件,轉換爲應用程序的依賴圖(和最終的 bundle)能夠直接引用的模塊。vue-cli

loader
  • loader讓 webpack 可以去處理那些非 JavaScript 文件

  • loader 能夠將全部類型的文件轉換爲 webpack 可以處理的有效模塊,而後你就能夠利用 webpack 的打包能力,對它們進行處理,本質上,webpack loader 將全部類型的文件,轉換爲應用程序的依賴圖(和最終的 bundle)能夠直接引用的模塊。

module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jsp|gif)/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 1024,
                        outputPath: 'imgs/',
                        publicPath: 'dist/'
                    }
                }]
                //或者你能夠簡寫成以下形式:
                //use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=images/&publicPath=dist/',
            }
        ]
    },
plugins - 插件
  • loader 被用於轉換某些類型的模塊,而插件則能夠用於執行範圍更廣的任務。插件的範圍包括,從打包優化和壓縮,

  • 想要使用一個插件,你只須要 require() 它,而後把它添加到 plugins 數組中。多數插件能夠經過選項(option)自定義。你也能夠在一個配置文件中由於不一樣目的而屢次使用同一個插件,這時須要經過使用 new 操做符來建立它的一個實例。

plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './index.html' //以當前目錄下的index.html文件爲模板生成dist/index.html文件
        }),
        new CleanWebpackPlugin(['dist']) ////傳入數組,指定要刪除的目錄
    ]

WebPack是一種模塊化管理方案/模塊打包工具,在他的眼裏就是萬物皆模塊,能夠用loader(加載器/轉換器)把任何一個文件資源打包成瀏覽器認識的JavaScript模塊.

實戰 - Vue-Cli

安裝插件:

一、首先webpack是在node環境下運行的,電腦環境中須要有node和npm,而且node版本必須是v8.5以上的,不然不支持webpack 4。
二、本地建立一個文件夾vue-cli,在vue-cli根目錄下打開cmd,而後在小黑窗中輸入npm init -y,生成package.json文件。
三、安裝插件Vue-loader和webpack:

  • webpack webpack-cli 本地再安裝一次
  • vue vue-loader webpack須要讀取vue文件並加載成它所認識的js
npm install vue webpack webpack-cli vue-loader

四、安裝靜態資源插件好比,img、style、css的loader和vue-template-compiler(用來編譯vue模板),url-loader封裝了file-loader,將咱們要求的格式的圖片轉換成計算機的base64編碼:

npm i style-loader css-loader url-loader file-loader vue-template-compiler -D
配置WebPack並打包項目

一、在根目錄下建立:src/index.jssrc/App.vuewebpack.config.jsindex.html

 

App.vue

<template>
    <div>
        Hello Webpack!
    </div>
</template>

<script>

</script>

<style scoped>

</style>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

index.js

/**
 @Author:Wyunfei
 @Date:2019/3/1/18:42
 @FileName: index.js
 */
import Vue from 'vue'
import App from './App.vue'
new Vue({
    el: '#app',
    components: { App },
    template: `<App />`
})

webpack.config.js

/**
 @Author:Wyunfei
 @Date:2019/3/1/18:44
 @FileName: webpack.config.js
 */
const Path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin');  // webpack 4版本以後加的,以前的版本不須要這個

let config = {
    entry: Path.resolve(__dirname, './src/index.js'), // 以join拼接path的形式配置絕對路徑,相對路徑打包後找不到會報錯
    output: {
        filename: 'vendor.build.js',
        path: Path.join(__dirname, 'dist')
    },
    module: {
        rules: [{
            test: /\.vue$/,
            loader: 'vue-loader'
        }, {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader'
            ]
        }, {
            test: /\.(png|jpg|jpeg|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    limit: 1024, // 判斷圖片的大小   若是小於1024就會轉換成base64
                    name: '[name].[ext]' // 輸出圖片的名字  ext是擴展名
                }
            }
        }]
    },
    plugins: [
        new VueLoaderPlugin()
    ]
};

module.exports = config;

上面配置好了以後還差最後一步,就是用webpack來執行配置跑項目,在scripts裏面加上build:
package.json

"build": "webpack --config webpack.config.js"

執行命令npm run build後會在根目錄下看到一個dist/vendor.build.js,就是咱們打包好的文件,這一步就省去了咱們不少的http請求,達到更優化的效果。

 

運行項目

一、如今項目已經打包好了,接下來開始運行咱們的項目,先創建一個屬於咱們的開發模式,這裏須要使用webpack-dev-server來啓動咱們的webpack.config.js,進而運行咱們的項目。使用它的東西第一步就是要安裝npm i webpack-dev-server,再往scripts裏面加上這個"dev": "webpack-dev-server --config webpack.config.js":

接下來增長一些開發模式須要用到的webpack的配置
二、webpack的編譯目標是web項目,因此咱們要target: 'web',放在全局的webpack的配置裏面

webpack.config.js

三、須要配置一個環境變量來區分咱們的生產環境和開發環境,輸入dos命令安裝npm i cross-env,在打包和運行以前都加上環境變量標識:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"
  },

四、再從webpack的配置里加個判斷,若是是開發環境,就把咱們的webpack服務放進去:
首先用一個變量表明是開發環境:const isDev = process.env.NODE_ENV === 'development';在package.json scripts裏面設置的生產和開發環境的環境變量都存在於cross-dev,咱們設置腳本的時候啓動的環境變量全都存在於process.env裏面,這樣咱們在以後能夠隨意調用它
而後在最下面給module.exports賦值以前,加個判斷:記住安裝npm install webpack-dev-server

webpack.config.js

if (isDev) {
    config.devServer = {
        port: 8088, // webpack服務須要監聽的端口號
        host: '0.0.0.0', // 能夠經過本機內網ip訪問,這樣別人也能夠訪問,手機也可訪問,若是設置成localhost則否則
        overlay: {
            errors: true // 這個無關緊要,webpack編譯出現的錯誤會出如今網頁中,便於更改
        }
    };
}

module.exports = config;

五、引入webpack,以便以後用webpack的插件,下面會用到DefinePlugin這個插件(ps:作vue或react的項目必須用到的,這些項目都會根據環境來區分打包)

const Webpack = require('webpack');

六、用法和以前的同樣,全部的插件都是須要引入並建立實例這一過程;下面根據以前配置好的環境變量在webpack編譯的過程當中,對寫的js代碼都會判斷環境,根據不一樣環境對代碼進行打包,代碼以下:

plugins: [
        new VueLoaderPlugin(),
        new Webpack.DefinePlugin({
            'process-env': {
                NODE_ENV: isDev ? '"development"' : '"production"'
            }
        })
    ]

七、這也是最後一步,咱們到如今爲止尚未一個網頁入口,先安裝一個html-webpack-plugin,一樣的引入配置好了,運行一下項目就ok了

const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
        new VueLoaderPlugin(),
        new Webpack.DefinePlugin({
            'process-env': {
                NODE_ENV: isDev ? '"development"' : '"production"'
            }
        }),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './index.html' //以當前目錄下的index.html文件爲模板生成dist/index.html文件
        })
    ]

運行結果:

訪問結果:

Vue項目開發

一、建立:src/components/index.vuesrc/router/index.jssrc/assets/css/index.css安裝npm install vue-router -D

components/index.vue

<template>
    <h1>
        Hello Vue-Router
    </h1>
</template>

<script>

</script>

<style scoped>

</style>

assets/css/index.css

/**
@Author:Wyunfei
@Date:2019/3/1/19:51
@FileName: index
*/
html,body {
    width: 100%;
    height: 100%;
    background: pink;
}

二、路由配置
router/index.js

/**
 @Author:Wyunfei
 @Date:2019/3/1/19:36
 @FileName: index.js
 */
import Vue from 'vue'
import Router from 'vue-router'
import Index from '../components/index.vue'

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: '/',
            component: Index
        }
    ]
})

src/index.js

/**
 @Author:Wyunfei
 @Date:2019/3/1/18:42
 @FileName: index.js
 */
import Vue from 'vue'
import App from './App.vue'
import './assets/css/index.css'
import router from './router/index.js'
new Vue({
    el: '#app',
    router,
    render: (h) => h(App)
})

components/index.vue

<template>
    <h1>
        Hello Components
    </h1>
</template>

<script>

</script>

<style scoped>

</style>

src/App.vue

<template>
    <div>
        Hello Webpack!
        <router-view />
    </div>
</template>

<script>

</script>

<style scoped>

</style>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

</div>
</body>
</html>

npm run dev就能夠經過localhost + 端口在瀏覽器訪問了
npm run build就能夠打包生成dist目錄了,放到服務器上,上線啦~~

 

本文轉自:https://www.jianshu.com/p/b06f38f0a429

相關文章
相關標籤/搜索