從頭開始-手把手用webpack4搭建vue/react環境

安穩.發表於2019-03-06

Created By JishuBao on 2019-03-06 12:38:22
Recently revised in 2019-03-08 12:38:22

 

  歡迎大家來到技術寶的掘金世界,您的star是我寫文章最大的動力!GitHub地址     

  開篇點題:   
  這是一篇使用webpack4搭建vue/react環境的文章,會詳細的介紹每個外掛的作用等...   
   感覺不錯的小夥伴,點贊star走一波;  
   感覺文章有誤的小夥伴,評論區、QQ群走一波;  
   虛心求教,不勝感激~  

一、Webpack概述

webpack是模組化管理工具,使用webpack可以對模組進行壓縮、預處理、按需打包、按需載入等。

二、webpack基本概念

在深入瞭解webpack之前我們先來了解幾個相關概念(知道大家懶得看,就粗略的介紹下):

  • Entry:入口,Webpack執行構建的第一步將從Entry開始,可抽象成輸入。
  • Module:模組,在Webpack裡一切皆模組,一個模組對應著一個檔案。webpack會從配置的Entry開始遞迴找出所有依賴的模組。
  • Chunk:程式碼塊,一個Chunk由多個模組組合而成,用於程式碼合併與切割。
  • Loader:模組轉換器,用於把模組原內容按照需求轉換成新內容。
  • Plugin:擴充套件外掛,在Webpack構建流程中的特定時機會廣播出對應的時間,外掛可以監聽這些事件的發生,在特定時機做對應的事情。

三、webpack實操(小白入門級別)

肯定有小夥伴們百度過其他的文章,也肯定遇到過只誇誇而談而不實際操作的博主,或者一些博主只是粗略的一筆帶過,導致大家啥也沒有收穫,越看越迷糊,本文與那些不負責任的博主是不一樣的(開個玩笑),本文真刀真槍,實際操作,帶小夥伴從零開始手動搭建一個webpack的開發環境,精細到新建資料夾級別(手動滑稽),爭取每一行程式碼大家看的見、理解的透徹!!

新建個資料夾

首先新建一個資料夾,技術寶喜歡在E盤的MyProject目錄下新建資料夾,取名叫做WebpackofVueStage,如下圖所示:

從頭開始-手把手用webpack4搭建vue/react環境

用編輯器開啟資料夾

使用編輯器開啟資料夾,我在這裡使用的是VSCODE,這是微軟推出的一款編輯器,非常好用,建議小夥伴們都可以來試試看哦~,如下圖所示:

從頭開始-手把手用webpack4搭建vue/react環境

在vscode終端中開啟這個資料夾,即在這個資料夾下開啟所在命令列,輸入npm init,會生成一個package.json檔案

從頭開始-手把手用webpack4搭建vue/react環境

內容如下

從頭開始-手把手用webpack4搭建vue/react環境

四、在目錄下新建檔案

在主目錄下新建build目錄存放webpack相關配置檔案、src目錄存放原始碼目錄包括資原始檔、js、css檔案等...,目錄結構入下圖所示,檔案均為空,技術寶將帶著大家一行行程式碼實現這"巨集偉"的專案。

從頭開始-手把手用webpack4搭建vue/react環境

五、磨刀霍霍敲起來

webpack相關檔案的程式碼編寫:此處將webpack檔案分為三個檔案

1.webpack.base.conf.js(基礎程式碼的編寫)

const path=require('path');
//利用require匯入了node中path模組,path模組了一些處理檔案路徑的小工具,由於webpack是基於Node環境下的工具,所以可以直接使用node原生模組path
複製程式碼
const SRC_PATH=path.resolve(__dirname,"../src")
//path.resolve()方法可以將路徑或者路徑片段解析成絕對路徑,具體可以結合官方文件進行檢視,綜合來看,path.resolve()是一個修改和整合檔案路徑的方法,dirname是directory+name的縮寫,故名思義,是檔名的意思。總的來說就是將絕對路徑提取出來
複製程式碼
entry:{
    main:'./src/index.js'
}
//入口起點(entry point)指示 webpack 應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模組和庫是入口起點(直接和間接)依賴的
複製程式碼

本文以vue為例,首先安裝需要安裝的依賴包

npm install vue -S
//-S即-save的縮寫,包會寫入dependencies,-D或者--save-d會寫入devDepencies中
複製程式碼
npm install webpack webpack-cli webpack-dev-server webpack-merge --save-dev
//webpack-cli是 webpack 的命令列工具。讓我們可以不用寫打包指令碼,只需配置打包配置檔案,然後在命令列輸入 webpack-cli --config webpack.config.js 來使用 webpack, 簡單很多。webpack 4 之前命令列工具是整合在 webpack 包中的,4.0 開始 webpack 包本身不再整合 cli。webpack-dev-server用於開發除錯,它提供了web服務、熱更新、介面代理等支援。webpack-merge提供了一個merge連線陣列併合並建立新物件的物件的函式。如果遇到函式,它將執行它們,通過演算法執行結果,然後再次將返回的值包裝在函式中。
複製程式碼
resolve:{
        extensions:['.vue','.js'],
        alias:{
            '@':SRC_PATH
        }
},
//Resolve 配置 Webpack 如何尋找模組所對應的檔案,extensions:在匯入語句沒帶檔案字尾時,Webpack 會自動帶上字尾後去嘗試訪問檔案是否存在。alias: 配置項通過別名來把原匯入路徑對映成一個新的匯入路徑。 
複製程式碼
module:{
        rules:[
            {
                test:/\.vue$/,//通過loader來預處理檔案 允許你打包除了js之外的任何靜態資源
                use:'vue-loader'
            },
            {
                test:/\.js?$/,
                use:'babel-loader',
                //排除node_modules目錄下的檔案
                exclude:/node_modules/,
                include:SRC_PATH
            },
            {
                test:/\.(woff|svg|eot|woff2|tff)$/,
                use:[
                    {
                        loader:'url-loader',
                        include: [resolve('src')],
                        options:{
                            limit:10000
                        }
                    }
                ],
                exclude:/node_modules/,
            }
        ]
    },
複製程式碼

如上:需要安裝圖示對應的loader

 npm install vue-loader babel-loader url-loader --save-dev
//rules是module的屬性,指定模組解析規則,而use是每一個rule的屬性,指定要用什麼loader。vue-loader:解析和轉換 .vue 檔案,提取出其中的邏輯程式碼 script、樣式程式碼 style、以及 HTML 模版 template,再分別把它們交給對應的 Loader 去處理。babel-loader用於將ES6轉化為ES5等功能。url-loader他可以將html以及css中的圖片打包成base64,但是js中如果有圖片url並不能編譯成功。用於減少http請求實現效能優化。
複製程式碼

當使用vue-loader時,請確保您已經引入vue的外掛

const VueLoaderPlugin = require('vue-loader/lib/plugin');
plugins:[
        new VueLoaderPlugin(),
        //它的職責是將你定義過的其它規則複製並應用到 .vue 檔案裡相應語言的塊。例如,如果你有一條匹配 /\.js$/ 的規則,那麼它會應用到 .vue 檔案裡的 <script> 塊。
]
複製程式碼

至此基礎webpack檔案已經搭建好,以下是webpack.base.conf.js的完整程式碼:

const path=require('path');
//path是node.js的一個模組,提供了一些用於處理檔案路勁的小工具
const SRC_PATH=path.resolve(__dirname,"../src");
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports={
    entry:{
        main:"./src/index.js"//入口起點(entry point)指示 webpack 應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模組和庫是入口起點(直接和間接)依賴的
    },
    resolve:{
        extensions:['.vue','.js'],
        alias:{
            '@':SRC_PATH
        }
    },
    module:{
        rules:[
            {
                test:/\.vue$/,//通過loader來預處理檔案 允許你打包除了js之外的任何靜態資源
                use:'vue-loader'
            },
            {
                test:/\.js$/,
                use:'babel-loader',
                //排除node_modules目錄下的檔案
                exclude:/node_modules/,
                include:SRC_PATH
            },
            {
                test:/\.(woff|svg|eot|woff2|tff)$/,
                use:[
                    {
                        loader:'url-loader',
                        options:{
                            limit:10000
                        }
                    }
                ],
                exclude:/node_modules/,
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin(),
        //它的職責是將你定義過的其它規則複製並應用到 .vue 檔案裡相應語言的塊。例如,如果你有一條匹配 /\.js$/ 的規則,那麼它會應用到 .vue 檔案裡的 <script> 塊。
    ]

}
複製程式碼

2.webpack.dev.conf.js的編寫(開發環境)

const webpack=require('webpack');
//require工作原理:首先確定是否是一個原生的模組,如果不是就進入node_modules查詢,再看是否在package.json的main裡面定義。
複製程式碼
const merge=require('webpack-merge');
//webpack-merge提供了一個merge連線陣列併合並建立新物件的函式。
複製程式碼
const baseWebpackConfig=require('./webpack.base.conf.js');
//引入基礎webpack設定。
複製程式碼
const HtmlWebpackPlugin=require('html-webpack-plugin');
//這是一個webpack外掛,可以簡化HTML檔案的建立,為您的webpack捆綁服務提供服務。這對於webpack在檔名中包含雜湊的包很有用,這些雜湊值會更改每個編譯。基本作用就是生成HTML。
複製程式碼
const derServerPort=10000;
//開發環境的埠號。
複製程式碼
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
//識別某些類別的webpack錯誤,並清理,聚合和優先順序,以提供更好的開發人員體驗。(友好的提示外掛)。
複製程式碼
npm install friendly-errors-webpack-plugin html-webpack-plugin --save-dev
//安裝上述程式碼所需要的依賴
複製程式碼
mode:'development'
//開發環境,會將 process.env.NODE_ENV 的值設為 development。啟用 NamedChunksPlugin 和 NamedModulesPlugin
複製程式碼
devtool:'cheap-module-eval-source-map'
//不帶列對映(column-map)的 SourceMap,將載入的 Source Map 簡化為每行單獨對映。.
複製程式碼
module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(sc|sa)ss$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"sass-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.less$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"less-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(png|svg|jpg|gif)$/,
                use:[
                    {
                        loader:'file-loader',
                        options:{
                            limit:10000,
                        }
                    }
                ]
            }
        ]
    },
//直接來說是把對應字尾名轉化為css檔案
複製程式碼
npm install style-loader css-loader sass-loader less-loader postcss-loader file-loader --save-dev
//使用style-loader通過注入<style>標記將CSS新增到DOM。css-loader 解釋(interpret) @import 和 url() ,會 import/require() 後再解析(resolve)它們。sass-loader:將 Sass 編譯成 CSS。less-loader:將less轉化為css。postcss-loadercss3屬性已經給加上了瀏覽器字首,file-loader與file-loader類似。
複製程式碼
devServer:{
        port:derServerPort,//指定要監聽請求的埠號
        overlay:{//當編譯器存在錯誤或警告時,將瀏覽器顯示全屏覆蓋
            warnings:false,
            errors:true,
        },
        host:"localhost",
        open:true,//開發伺服器將開啟瀏覽器
        noInfo:true,//那些顯示的 webpack 包(bundle)資訊」的訊息將被隱藏。錯誤和警告仍然會顯示。
        https:false,
        hot:true,//啟用webpack的模組熱更新
        compress:true,//一切服務都啟用gzip壓縮
        progress:true,//將任務進度輸出到控制檯
        quiet:true,
        useLocalIp:false,//此選項允許瀏覽器使用你的本地ip開啟
        proxy:{//代理伺服器
            "/api":{
                target:"http://localhost:8080",
                changeOrigin:true,
                pathRewrite:{"^api":"/api"}
            }
        }
    },
    //以上為webpack開發模式下的程式碼片段
複製程式碼
plugins:[
        //處理html
        new HtmlWebpackPlugin({
            template:'src/public/index.html',//開發環境需要路徑
            inject:'body',//所有javascript資源將被放置在body元素的底部
            minify:{
                html5:true,
                collapseWhitespace: true, //把生成的 index.html 檔案的內容的沒用空格去掉,減少空間
            },
            title:'基於vue的webpack4教手架專案 準備在專案中採用vue-router、vuex、vant等技術(development開發環境)',
            hash:true,
            favicon:'src/assets/favicon-shield.ico',//將給定的favicon路徑新增到輸出HTML
            showErrors:true,
        }),
        //熱更新
        new webpack.HotModuleReplacementPlugin(),
        new FriendlyErrorsWebpackPlugin({
            compilationSuccessInfo: {
                messages: [`You application is running here http://localhost:${derServerPort}`],
                notes: ['Some additionnal notes to be displayed unpon successful compilation']
            },
            onErrors: function (severity, errors) {},
            clearConsole: true,
            additionalFormatters: [],
            additionalTransformers: []
        }),
        new webpack.LoaderOptionsPlugin({
            options:{
            }
        })
    ]
    //開發環境下的外掛配置
複製程式碼

至此開發環境下的webpack已搭好,webpack.dev.conf.js檔案完整程式碼如下:

const webpack=require('webpack');
//require工作原理:首先確定是否是一個原生的模組,如果不是就進入node_modules查詢,再看是否在package.json的main裡面定義。
const merge=require('webpack-merge');
//webpack-merge提供了一個merge連線陣列併合並建立新物件的函式
const baseWebpackConfig=require('./webpack.base.conf.js');
//引入基礎webpack設定
const HtmlWebpackPlugin=require('html-webpack-plugin');
const derServerPort=10000;
//基本作用就是生成html檔案
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
//友好的提示

module.exports=merge(baseWebpackConfig,{
    mode:'development',//開發環境,會將 process.env.NODE_ENV 的值設為 development。啟用 NamedChunksPlugin 和 NamedModulesPlugin
    devtool:'cheap-module-eval-source-map',//不帶列對映(column-map)的 SourceMap,將載入的 Source Map 簡化為每行單獨對映。
    module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(sc|sa)ss$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"sass-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.less$/,
                use:[
                    {loader:"style-loader"},
                    {loader:"css-loader"},
                    {loader:"less-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(png|svg|jpg|gif)$/,
                use:[
                    {
                        loader:'file-loader',
                        options:{
                            limit:10000,
                        }
                    }
                ]
            }
        ]
    },
    devServer:{
        port:derServerPort,//指定要監聽請求的埠號
        overlay:{//當編譯器存在錯誤或警告時,將瀏覽器顯示全屏覆蓋
            warnings:false,
            errors:true,
        },
        host:"localhost",
        open:true,//開發伺服器將開啟瀏覽器
        noInfo:true,//那些顯示的 webpack 包(bundle)資訊」的訊息將被隱藏。錯誤和警告仍然會顯示。
        https:false,
        hot:true,//啟用webpack的模組熱更新
        compress:true,//一切服務都啟用gzip壓縮
        progress:true,//將任務進度輸出到控制檯
        quiet:true,
        useLocalIp:false,//此選項允許瀏覽器使用你的本地ip開啟
        proxy:{//代理伺服器
            "/api":{
                target:"http://localhost:8080",
                changeOrigin:true,
                pathRewrite:{"^api":"/api"}
            }
        }
    },
    plugins:[
        //處理html
        new HtmlWebpackPlugin({
            template:'src/public/index.html',//開發環境需要路徑
            inject:'body',//所有javascript資源將被放置在body元素的底部
            minify:{
                html5:true,
                collapseWhitespace: true, //把生成的 index.html 檔案的內容的沒用空格去掉,減少空間
            },
            title:'基於vue的webpack4教手架專案 準備在專案中採用vue-router、vuex、vant等技術(development開發環境)',
            hash:true,
            favicon:'src/assets/favicon-shield.ico',//將給定的favicon路徑新增到輸出HTML
            showErrors:true,
        }),
        //熱更新
        new webpack.HotModuleReplacementPlugin(),
        new FriendlyErrorsWebpackPlugin({
            compilationSuccessInfo: {
                messages: [`You application is running here http://localhost:${derServerPort}`],
                notes: ['Some additionnal notes to be displayed unpon successful compilation']
            },
            onErrors: function (severity, errors) {},
            clearConsole: true,
            additionalFormatters: [],
            additionalTransformers: []
        }),
        new webpack.LoaderOptionsPlugin({
            options:{
                // postcss:[
                //     require('postcss-plugin-px2rem')({
                //         rootValue:75,
                //         selectorBlackList:['html'],
                //         mediaQuery:true,
                //         propBlackList:['75px']
                //     })
                // ],
            }
        })
    ]
});
複製程式碼

3.webpack.prod.conf.js程式碼的編寫(生產環境)

與上文中程式碼相同不再贅述

const path=require('path');
const DIST_PATH=path.resolve(__dirname,"../dist");
const CleanWebpackPlugin=require('clean-webpack-plugin');
//打包之前清除檔案
複製程式碼
const BundleAnalyzerPlugin=require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//分析打包後的包體積大小等
複製程式碼
const MiniCssExtractPlugin=require('mini-css-extract-plugin');
//分離css
複製程式碼
 mode:"production"
 //會將 process.env.NODE_ENV 的值設為 production。啟用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
複製程式碼
output:{
        filename:"js/[name].[hash].js",
        path:DIST_PATH
},
複製程式碼
module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(sc|sa)ss$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:"sass-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.less$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:'less-loader'},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(png|svg|jpg|gif)$/,
                use:[
                    {
                        loader:'file-loader',
                        options:{
                            limit:10000,
                            name:"[hash].[ext]",
                            outputPath:"images/"
                        }
                    }
                ]
            }
        ]
    },
    //與開發模式下基本相同,MiniCssExtraPlugin外掛分離css檔案
複製程式碼
plugins:[
        new CleanWebpackPlugin(['dist'],{root:path.resolve(__dirname,'../'),verbose:true}),//每次打包前清除dist
        new HtmlWebpackPlugin({
            //將目錄下的index.html引進生成的dist中的index.html
            template:'src/public/index.html',
            title:'基於vue的webpack4教手架專案 準備在專案中採用vue-router、vuex、vant等技術(product生產環境)',
            favicon:'src/assets/favicon-shield.ico',
            minify:{
                removeComments:true,
                collapseWhitespace:true,
                removeAttributeQuotes:true
            },
            
        }),
        new BundleAnalyzerPlugin({//打包分析
            analyzerPort:10000,
            openAnalyzer:true,
        }),
        new MiniCssExtractPlugin({//分離css
            filename:"css/[name].[chunkhash:8].css",
            chunkFilename:"css/[id].[hash]css"
        })
    ]
複製程式碼

至此webpack生產環境已經搭建完成,完整程式碼如下:

const merge=require('webpack-merge');
const baseWebpackConfig=require('./webpack.base.conf.js');
const webpack=require('webpack');
const path=require('path');
const DIST_PATH=path.resolve(__dirname,"../dist");
//打包之前清除檔案
const CleanWebpackPlugin=require('clean-webpack-plugin');
const HtmlWebpackPlugin=require('html-webpack-plugin');
//打包的時候分析包大小等
const BundleAnalyzerPlugin=require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//分離css
const MiniCssExtractPlugin=require('mini-css-extract-plugin');

module.exports=merge(baseWebpackConfig,{
    mode:"production",//會將 process.env.NODE_ENV 的值設為 production。啟用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
    devtool:'cheap-module-source-map',//不帶列對映(column-map)的 SourceMap,將載入的 Source Map 簡化為每行單獨對映。
    output:{
        filename:"js/[name].[hash].js",
        path:DIST_PATH
    },
    module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(sc|sa)ss$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:"sass-loader"},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.less$/,
                use:[
                    MiniCssExtractPlugin.loader,
                    {loader:'css-loader'},
                    {loader:'less-loader'},
                    {loader:"postcss-loader"}
                ]
            },
            {
                test:/\.(png|svg|jpg|gif)$/,
                use:[
                    {
                        loader:'file-loader',
                        options:{
                            limit:10000,
                            name:"[hash].[ext]",
                            outputPath:"images/"
                        }
                    }
                ]
            }
        ]
    },
    plugins:[
        new CleanWebpackPlugin(['dist'],{root:path.resolve(__dirname,'../'),verbose:true}),//每次打包前清除dist
        new HtmlWebpackPlugin({
            //將目錄下的index.html引進生成的dist中的index.html
            template:'src/public/index.html',
            title:'基於vue的webpack4教手架專案 準備在專案中採用vue-router、vuex、vant等技術(product生產環境)',
            favicon:'src/assets/favicon-shield.ico',
            minify:{
                removeComments:true,
                collapseWhitespace:true,
                removeAttributeQuotes:true
            },
            
        }),
        new BundleAnalyzerPlugin({//打包分析
            analyzerPort:10000,
            openAnalyzer:true,
        }),
        new MiniCssExtractPlugin({//分離css
            filename:"css/[name].[chunkhash:8].css",
            chunkFilename:"css/[id].[hash]css"
        })
    ]
});
複製程式碼

src相關檔案的程式碼編寫

如上述,我們已經完成了與webpack相關的程式碼編寫。接下來就是原始碼相關的編寫了在上面敲的程式碼中我們會發現例如index.js、index.html等都未進行程式碼的編寫,接下來我們就要完善這部分的程式碼。Are you ready?

1.首先準備css圖示圖片favicon-shield.ico(ico字尾是圖表圖片格式),放入assets資料夾

從頭開始-手把手用webpack4搭建vue/react環境

2.index.html模板檔案的編寫,放入public資料夾下

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
        <title>
            <%= htmlWebpackPlugin.options.title %>
        </title>
    </head>
    <body>
        <div id="root"></div>
    </body>
</html>
複製程式碼

3.入口檔案index.js的編寫,放入src根目錄下:

import Vue from 'vue';
//在import Vue的過程中Vue主要是在原型上完成方法的掛載,並且初始化了全域性的API。
import App from './App.vue';//引入vue頁面(稍候書寫)
import './styles/reset.css';//引入樣式重置

Vue.config.productionTip=false;//阻止啟動生產訊息,常用作指令

new Vue({
    el:"#root",//將渲染結果掛在這id為root的html上
    render:h=>h(App),//render函式是渲染一個檢視,然後提供給el掛載,如果沒有render那頁面什麼都不會出來
});
複製程式碼

解析vue template 標籤要安裝制定依賴

npm install vue-template-compiler --save-dev
複製程式碼

4.在src目錄下編寫app.vue頁面

<template>
    <div class="container"><span>{{msg}}</span></div>
</template>

<script>
export default {
    data(){
        return{
            msg:'webpack4搭建react環境基本完成,是不是很簡單呢'
        }
    }
}
</script>

<style>
.container{
    display:flex;
    justify-content:center;
    align-items:center;
    font-size:20px;
    color:red;
    box-shadow:5px 5px 5px 5px;
}
</style>
複製程式碼

5.編寫樣式檔案reset.css

/* 
  * reset 的目的不是讓預設樣式在所有瀏覽器下一致,而是減少預設樣式有可能帶來的問題。
  * The purpose of reset is not to allow default styles to be consistent across all browsers, but to reduce the potential problems of default styles.
  * create by jsliang
*/

/** 清除內外邊距 - clearance of inner and outer margins **/
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* 結構元素 - structural elements */
dl, dt, dd, ul, ol, li, /* 列表元素 - list elements */
pre, /* 文字格式元素 - text formatting elements */
form, fieldset, legend, button, input, textarea, /* 表單元素 - from elements */
th, td /* 表格元素 - table elements */ {
  margin: 0;
  padding: 0;
}

/*預設初始化樣式*/
body{
  margin:0;padding:0;font-size:"微軟雅黑";box-sizing: border-box;
}

body,html{
  text-size-adjust: none;/*文字不會隨著裝置尺寸的變化而變化*/
  width:100%;
  height:100%;
}

*{text-decoration: none;list-style:none;}

img{border:0px;}

/** 設定預設字型 - setting the default font **/
body, button, input, select, textarea {
  font: 18px/1.5 '黑體', Helvetica, sans-serif;
}
h1, h2, h3, h4, h5, h6, button, input, select, textarea { font-size: 100%; }

/** 重置列表元素 - reset the list element **/
ul, ol { list-style: none; }

/** 重置文字格式元素 - reset the text format element **/
a, a:hover { text-decoration: none; }

/** 重置表單元素 - reset the form element **/
button { cursor: pointer; }
input { font-size: 18px; outline: none; }

/** 重置表格元素 - reset the table element **/
table { border-collapse: collapse; border-spacing: 0; }

/** 圖片自適應 - image responsize **/
img { border: 0; display: inline-block; width: 100%; max-width: 100%; height: auto; vertical-align: middle; }

/* 
    * 預設box-sizing是content-box,該屬性導致padding會撐大div,使用border-box可以解決該問題
    * set border-box for box-sizing when you use div, it solve the problem when you add padding and don't want to make the div width bigger
*/
div, input { box-sizing: border-box; }

/** 清除浮動 - clear float **/
.jsbao-clear:after, .clear:after {
  content: '\20';
  display: block;
  height: 0;
  clear: both;
}
.jsbao-clear, .clear {
  *zoom: 1;
}

/** 設定input的placeholder - set input placeholder **/
input::-webkit-input-placeholder { color: #919191; font-size: .26rem } /* Webkit browsers */
input::-moz-placeholder { color: #919191; font-size: .26rem } /* Mozilla Firefox */
input::-ms-input-placeholder { color: #919191; font-size: .26rem } /* Internet Explorer */
複製程式碼

6.配置package.json檔案

npm install cross-env --save-dev
//解決webpack命令設定node_env=development無反應等 可跨平臺使用
複製程式碼

在package.json中的scripts標籤中寫入

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "cross-env webpack-dev-server --config build/webpack.dev.conf.js",
    "build": "cross-env webpack --config build/webpack.prod.conf.js"
 },
複製程式碼

7.關於babel

大家都知道babel在程式設計中的重要性,當然搭建Vue環境也是不可缺少的,讓我們看看常用的babel都有哪些呢(新版本已出,本文全線升級成babel 7.x以上)

@babel/core:@babel/core的作用是把 js 程式碼分析成 ast ,方便各個外掛分析語法進行相應的處理。

npm install @babel/core@7.1.2 --save-dev
複製程式碼

@babel/plugin-proposal-class-properties的作用是把es6的類轉化為瀏覽器可讀的

npm install @babel/plugin-proposal-class-properties@7.1.0 --save-dev
複製程式碼

@babel/plugin-proposal-decorators的作用是把裝飾器轉為為未瀏覽器可讀的

npm install @babel/plugin-proposal-decorators@7.1.6 --save-dev
複製程式碼

@babel/plugin-proposal-function-bind的作用是把::作用於繫結符轉化未瀏覽器可讀的

npm install @babel/plugin-proposal-function-bind@7.0.0 --save-dev
複製程式碼

@babel/plugin-syntax-dynamic-import的作用是支援promise和陣列的迭代相關的方法

npm install @babel/plugin-syntax-dynamic-import@7.0.0 --save-dev
複製程式碼

@babel/plugin-transform-runtime的作用會自動polyfill es5不支援的特性

npm install @babel/plugin-transform-runtime@7.1.0 --save-dev
複製程式碼

@babel/polyfill:這個庫將會模擬一個完全的 ES2015+ 的環境。這意味著你可以使用 新的內建語法 比如 promise 或者 WeakMap, 靜態方法比如Array.from 或 Object.assign, 例項方法 比如 Array.prototype.includes 和 generator 函式。

npm install @babel/polyfill@7.2.5 --save-dev
複製程式碼

@babel/preset-env是一個智慧預設,允許您使用最新的JavaScript,

npm install @babel/preset-env@7.1.6 --save-dev
複製程式碼

@babel/preset-react:轉化react中jsx的寫法

npm install @babel/preset-react@7.0.0 --save-dev
複製程式碼

@babel/preset-stage-0:同env

npm install @babel/preset-stage-0@7.0.0 --save-dev
複製程式碼

@babel/runtime:同@babel/polyfill

npm install @babel/runtime@7.2.0 --save-dev
複製程式碼

安裝了這些babel以後,需要有個檔案進行標識,src目錄下新建.babelrc

{
    "presets":[
        ["@babel/preset-env", {
            "modules": false,
            "targets": {
              "browsers": ["> 1%", "last 2 versions", "ie >= 10"]
            },
            "useBuiltIns": "usage"
        }],
        "@babel/preset-react"
    ],
    "plugins":[
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties",{"loose":true}],
        "@babel/plugin-transform-runtime",
        "@babel/plugin-proposal-function-bind",
        "@babel/plugin-syntax-dynamic-import"
    ]
}
複製程式碼

8.關於外部postcss.config.js的設定

因為你在loader 中引用了外掛,但是沒有指明是誰的外掛,需要制定一個ident,唯一標識。
src目錄下新建postcss.config.js檔案

//自動新增css相容屬性
module.exports = {
    plugins: [
        require('autoprefixer')({
            "browsers": [
                "defaults",
                "not ie < 11",
                "last 2 versions",
                "> 1%",
                "iOS 7",
                "last 10 versions"
            ]
        })
    ]
};
複製程式碼
npm install autoprefixer --save-dev
//,就是自動補全css字首的東西
複製程式碼

六、專案執行

是不是和我一樣看的很累呢,第一次寫文章很多地方沒有特別注意,希望下次可以越來越好吧 **扯了那麼多,不看效果等於耍流氓!!! 命令列執行npm run start/npm start 瀏覽器會自動彈出,建議你用谷歌(手動滑稽)
效果圖:

從頭開始-手把手用webpack4搭建vue/react環境

還是特別的醜 只有一行字 且垂直居中 不過我們們主要目的不是為了搭建webpack嘛!!!覺得此篇文章對你有用的畫不要忘了給我的git一個贊哦!!!

七、webpack執行原理

Webpack的執行流程是一個序列的過程,從開始到結束後回依次執行以下流程:

流程概括:

  • 1.初始化引數:從配置檔案和shell語句中讀取與合併引數,得出最終的引數
  • 2.開始編譯:用上一步得到的引數初始化 Compiler 物件,載入所有配置的外掛,執行物件的 run 方法開始執行編譯;
  • 3.確定入口:根據配置中的 entry 找出所有的入口檔案;
  • 4.編譯模組:從入口檔案出發,呼叫所有配置的 Loader 對模組進行翻譯,再找出該模組依賴的模組,再遞迴本步驟直到所有入口依賴的檔案都經過了本步驟的處理;
  • 5.完成模組編譯:在經過第4步使用 Loader 翻譯完所有模組後,得到了每個模組被翻譯後的最終內容以及它們之間的依賴關係;
  • 6.輸出資源:根據入口和模組之間的依賴關係,組裝成一個個包含多個模組的 Chunk,再把每個 Chunk 轉換成一個單獨的檔案加入到輸出列表,這步是可以修改輸出內容的最後機會;
  • 7.輸出完成:在確定好輸出內容後,根據配置確定輸出的路徑和檔名,把檔案內容寫入到檔案系統。

流程細節:

Webpack 的構建流程可以分為以下三大階段:

  • 初始化:啟動構建,讀取與合併配置引數,載入 Plugin,例項化 Compiler。
  • 編譯:從 Entry 發出,針對每個 Module 序列呼叫對應的 Loader 去翻譯檔案內容,再找到該 Module 依賴的 Module,遞迴地進行編譯處理。
  • 輸出:對編譯後的 Module 組合成 Chunk,把 Chunk 轉換成檔案,輸出到檔案系統。

如果只執行一次構建,以上階段將會按照順序各執行一次。但在開啟監聽模式下,流程將變為如下:

如果你覺得我的文章還不錯的話,可以給個star哦~,GitHub地址

下一步計劃是用Vue-router+Vuex+Vant寫一個簡易demo

相關文章