本節咱們將要說到的實戰場景目錄:javascript
- 入門配置
- 建立單頁面應用
- 接入babel
- 接入scss
- 接入vue
- 分離javascript與css
- 壓縮javascript
- 壓縮css
- 提取javascript公共代碼
- 加入代碼規範檢測
- 搭建本地服務
- 建立多頁面應用
目錄結構以下: css
webpack.config.js配置以下:html
const path = require('path');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist') //必須是絕對路徑
}
};
複製代碼
以上是一個最基礎的配置,咱們接下來一步一步的加入更多的功能.vue
首先,咱們經過第一節,能夠知道了怎麼將一個入口main.js打包成bundle.js了,那麼入口文件確定是要引用在html中啊,那麼,怎麼建立html文件?怎麼建立build之後的html文件,以及html文件如何引用入口js文件?答案就是 html-webpack-plugin。 點擊查看官方文檔java
該插件能夠實現哪些功能呢?node
第一步:安裝插件react
npm i html-webpack-plugin --save-dev
複製代碼
第二步:配置插件jquery
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './index.html'
})
]
說明:
template:表示模版,即以哪一個html文件爲模,在dist目錄下生成新的html文件
filename: 即編譯之後生成的html文件的名字
複製代碼
注意:上面咱們說到不用咱們手動建立一個html文件,就能夠在編譯後自動生成一個index.html, 固然,咱們也能夠建立一個html模版文件,而後經過template屬性引入, 這樣編譯後生成的index.html內容就是咱們本身建立的模版html文件的內容)webpack
如下是咱們生成的index.html文件: es6
babel完成了兩件事情:
- 它是一個javascript解釋器,它能夠將es6代碼轉換爲es5代碼,讓咱們在使用語言新特性的時候,不用擔憂兼容性問題。
- 它能夠經過插件機制,根據需求靈活的拓展。
在 Babel 執行編譯的過程當中,會從項目根目 錄下 的 .babelre 文件中讀取配置。 .babelrc 是一個 JSON 格式的文件,內容大體以下:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2",
"react"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
複製代碼
咱們來認識一下這兩個屬性:
第一步:在webpack中配置babel-loader。
module.exports = {
module: {
rules : [
{
test: /\.js$/ ,
use : ['babel-loader'],
}
//此處還能夠在rules下配置其餘loader
]
}
}
複製代碼
第二步:在根目錄下建立.babelrc文件,配置presets和plugins
{
"presets": [
"env"
],
"plugins": []
}
複製代碼
注意:webpack4.x支持在package.json中直接配置babel屬性,不用新建.babelrc便可
"babel": {
"presets": [
"env"
],
"plugins": []
}
複製代碼
第三步:安裝babel相關依賴
# Webpack 接入 Babel 必須依賴的模塊
npm i -D babel-core babel-loader
#根據咱們的需求選擇不一樣的 Plugins 或 Presets
npm i -D babel-preset-env
複製代碼
提示:以上實例代碼主要用於說明整個接入webpack的過程,在不一樣場景下,具體的配置和安裝依賴狀況也會有所不一樣。
scss 即爲了咱們書寫css更方便且更有效率,出現了less,sass,scss等css的預處理器,那麼,在最後部署上線的時候,依然要轉成css,才能夠在瀏覽器端運行。
第一步:安裝依賴
#安裝 Webpack Loader 依賴
npm i -D sass-loader css-loader style-loader
# sass-loader 依賴 node-sass
npm i 一D node-sass
複製代碼
第二步:在module中配置
module:{
rules:[
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
}
複製代碼
說明:
以上是配置wepbakc接入scss的基本配置, 除此以外,咱們還能夠加入優化配置:
你們可能都知道,vue,react等都是近些年來比較流行的mvvm框架,而咱們使用的過程當中,更可能是依賴vue-cli等自帶的腳手架去生成項目模版,不須要咱們手動去配置,那麼接下來,咱們就經過webpack去手動接入vue,這樣有利於咱們更好的理解vue。
第一步:安裝依賴
# Vue 框架運行須要的庫
npm i -S vue
#構建所需的依賴
npm i -D vue-loader css-loader vue-template-compiler
複製代碼
說明:
第二步:配置loader
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module:{
rules:[
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
],
複製代碼
注意:須要配置VueLoaderPlugin 插件,
提示:Vue-loader在15.*以後的版本都是 vue-loader的使用都是須要伴生 VueLoaderPlugin的第三步:引入vue文件
//此時就和vue-cli提供的模版main.js同樣去引入vue和vue相關文件
import Vue from 'vue';
import App from './app.vue';
new Vue({
el: '#app',
render: h => h(App)
});
複製代碼
默認狀況下,咱們打包entry入口文件的時候,文件中所依賴的css等樣式模塊也會包含js中,那麼,如何分離javascript和css,分別存放在不一樣的文件中呢?
第一步:安裝依賴
說明:Webpack 4.x已經再也不支持extract-text-webpack-plugin,推薦使用mini-css-webpack-plugin, 若是想繼續使用該插件,請 參考該文檔
此處,咱們依然用該插件來實現js與css的代碼分離:
//安裝插件
npm i extract-text-webpack-plugin@next --save-dev
注意: 後面的@next必須加上,webpack4.x只支持該版本
或者能夠用一個新插件: mini-css-extract-plugin
複製代碼
第二步:增長webpack配置
const ExtractTextPlugin = require ('extract-text-webpack-plugin');
module.exports = {
module:{
rules:[
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin({
filename: path.resolve(__dirname, '/style/bundle.css') //注意能夠指定分離出來的css文件的指定目錄
})
]
};
複製代碼
此時,咱們就能夠在build之後的dist文件夾裏,看到分離出來的css文件了。
例如:下面是一個文件目錄結構:
咱們在main.js中引入了main.css這個樣式文件,那麼,經過咱們webpack打包,而且進行javascript與css分離,dist中就分別生成了獨立的js文件和css文件。
經過上面的操做,咱們已經將javascript與css分離開來,打開css文件,咱們發現,此刻css文件是位被壓縮的,
那接下來,咱們接入css壓縮相關配置: 第一步:安裝依賴
npm i optimize-css-assets-webpack-plugin --save-dev
複製代碼
第二步:添加配置
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.export = {
plugins: [
//只要配置了該插件,便可對分離出來的css進行壓縮
new OptimizeCssAssetsPlugin()
]
}
複製代碼
最後,咱們再次build,發現dist中css已是被壓縮的了。
首先說明一點,可能咱們會看到不少教程使用的是UglifyJsPlugin,不過是webpack4.x以前的版本可使用,webpack4.x已經不支持使用移除webpack.optimize.UglifyJsPlugin 壓縮配置了, 推薦使用 optimization.minimize 屬性替代。
代碼以下:
module.exports = {
optimization: {
minimize: true //webpack內置屬性,默認爲true,
}
}
複製代碼
注意:minimize屬性默認爲 true,即默認狀況下build以後的js文件已是壓縮的了,若是咱們不想壓縮js,能夠設置該屬性爲false,
咱們來看看實際壓縮先後的區別:
一: 首先,咱們說明一下爲何要提取公共代碼?:
大型網站一般由多個頁面組成, 每一個頁面都是一個獨立的單頁應用。 但因爲全部頁面都 採用一樣的技術枝及同 一套樣式代碼,就致使這些頁面之間有很 多相同的代碼。
若是每一個頁面的代碼都將這些公共的部分包含進去,則會形成如下問題 。
因此,在實際開發過程當中,咱們須要把公共的代碼抽離成一個獨立的文件,這樣用戶在首次訪問網站是就加載了該獨立公共文件,此時這些公共文件就被瀏覽器緩存起來了,切換到其餘頁面時,該公共文件就不用在從新請求,而是直接訪問緩存接口。
二:實際開發中,都須要咱們提取哪些公共文件呢
一說到公共文件,咱們可能最早想到是一些公共的工具函數所在的common.js文件,這個公共文件中的工具函數會被多個頁面同時使用,其實,還有一個base.js也就是最基礎的文件,例如,咱們vue開發過程當中的vue.js,
因此,此處所說的公共文件包含如下兩部分:
注意:此處咱們爲何要把base.js也單獨提取出來,而不是直接包含在common.js中呢? 答案:爲了長期長期緩存base.js文件,
由於base.js中包含的都是一些基礎庫,並且是指定版本的,咱們平時開發過程當中,通常不會升級這些基礎庫的版本,全部只要基礎庫版本不升級,文件內容就不會變化,hash值也不會更新,那麼以前在瀏覽器中留下的緩存也不會被更新,從而實現長期緩存。而common.js是依據咱們開發的內容來的,因此若是開發過程當中發生了變化,那麼hash也變化,從新上線之後再次訪問,原來的緩存的common.js就沒法使用了,會使用新的common.js文件。
三: 最後,咱們來因此說一下,如何經過webpack提取公共代碼?
首先說明如下:webpack4.x提取公共代碼推薦使用:webpack內置的SplitChunksPlugin插件,4.x以前所使用的CommomsChunksPlugin已被淘汰
接下來,咱們來經過具體的例子試一下:
第一步:咱們建立了兩個入口文件:main.js 和 index.js, 還有一個公共的common.js文件,同時再安裝一個lodash第三方庫,而後兩個入口文件中,分別引入common.js和lodash;
// mian.js和index.js
import './assets/js/common';
import 'lodash';
複製代碼
第二步:配置多入口文件:
module.export = {
entry: {
main: './src/main.js',
index: './src/index.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
複製代碼
第三步:此時,咱們執行npm run build命令,生成的dist文件夾以下:
此時,咱們引入的lodash和common.js其實分別在main.bundle.js和index.bundle.js各打包了一份,很顯然,這樣是不對的,那麼如何把common.js和lodash分離打包成獨立的文件呢? 答案就是splitChunks屬性
第四步:配置splitChunks屬性
module.exports = {
optimization: {
splitChunks: {
chunks: "async",
}
}
}
複製代碼
此時,咱們執行npm run build發現 dist中的文件沒有任何變化,並無將 公共模塊分離出來,緣由是爲何呢?
webpack4.x其實默認會將公共文件抽取出來的,只不過chunks屬性默認是async, 顧名思義該詞是異步的意思,也就是說默認狀況下,webpack4.x只會將異步的公共模塊分離成獨立的文件, 而咱們手動引入的common.js和lodash是同步引入的,因此沒有分離出來,因此咱們須要把chunks屬性改成‘initial’ 或者‘all’
module.exports = {
optimization: {
splitChunks: {
chunks: "initial",
}
}
}
複製代碼
咱們再來看一下dist目錄:
咦,有了,多了一個vendors~index~main.bundle.js, 也就是說common.js和lodash已經分離出來了,都被存放在 vendors~index~main.bundle.js 中,可是還差一步:如何讓common.js和lodash分別分離成獨立的文件呢?
首先,咱們分析如下緣由,實際上是minSize屬性致使的,它默認值爲30000,也就是說webpack4.x只會將文件大小大於3k的公共文件分離出來,而咱們目前的common.js大小還不夠,因此沒有單獨分離成一個文件,很顯然,此時只須要修改minSize的值便可。
module.exports = {
optimization: {
splitChunks: {
chunks: "initial",
minSize: 0
}
}
}
複製代碼
咱們再來看看dist目錄:
啦啦啦,終於搞定了,lodash等屬於nodemules中的公共依賴,都被分離到vendors~index~main.bundle.js中,而common.js被分離到main~index.bundle.js中,至此,如何提取公共js文件,大功告成!
Npm Script Chttps://docs.npm s.com/misc/scripts)是一個任務執行者。 Npm 是在安裝 Node.js 時附帶的包管理器, Npm Script 則是 Npm 內置的 一個功能,容許在 package.json 文件裏 使用 scripts 宇段定義任務:
{
"scripts": {
'dev': 'node dev.js',
'build': 'node bulid.js'
}
}
複製代碼
以上代碼中的 scripts 字段是 一 個對象,每一個屬性對應一段腳本,以上代碼定義 了兩 個任務 dev 和 build。 Npm Script 的底層實現原理是經過調用 Shell 去運行腳本命令, 例如執 行 npm run build 命令等同於執行 node build.j s 命令。
同時npm script能夠執行node_modules內置的模塊:
例如:
{
"scripts": {
"build": "webpack"
}
}
複製代碼
檢查代碼時主要檢查如下幾項:
目前最經常使用的 JavaScript 檢查工具是 ESlint (eslint.org),它不只內 置了大量的經常使用檢查 規則,還能夠經過插件機制作到靈活擴展。
npm i eslint --save-dev //局部安裝
或者
npm i eslint -g //全局安裝
複製代碼
第二步:建立.eslintrc
{
//從 eslint :recommended 中繼承全部檢查規則
"extends" : "eslint:recommended",
// 再自定義一些規則
」rules」:{
//須要在每行結尾加 ;
"semi":["error","always"] , //須要使用""包裹字符串
"quotes" : [ "error", "double"]
}
}
複製代碼
第三步:運行eslint命令
eslint yourfile . js
複製代碼
該命令的做用就是檢查yourfile.js文件的代碼格式是否符合eslint的要求,若是有問題會報警提示:例如:
296:13 error Strings must use doublequote quotes
298 :7 error Missing semicolon sem工
複製代碼
npm i eslint-loader -D
複製代碼
第二步:添加loader
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter') // 默認的錯誤提示方式
}
},
enforce: 'pre', // 編譯前檢查
exclude: /node_modules/, // 不檢測的文件
include: [__dirname + '/src'], // 要檢查的目錄
}
]
}
複製代碼
第三步:新建.eslintrc.js
複製代碼
stylelint (stylelint.io)是目前最成熟的 css 檢查工具,在內置了大量檢查規則的 同時,也提供了插件機制讓用戶自定義擴展 。 stylelint 基於 PostCSS,能檢查任何 PostCSS 能解析的代碼,例如 scss、 Less 等 。
npm i stylelint --save-dev
或者
ηpm i -g stylelint
複製代碼
第二步:建立.stylelintrc文件
{
//繼承 stylelint-config-standard 中全部的檢查規則
"extends":"stylelint-config-standard",
// 再自定義檢查規則
"rules": {
"at-rule-empty-line-before": null
}
}
複製代碼
第三步:執行命令
stylelint 」yourfile.css」
複製代碼
第一步. 搭建本地服務webpack-dev-server
npm install webpack-dev-server --save-dev
複製代碼
第二步:在package.json配置npm script命令
scripts: {
"dev": 'webpack-dev-server --config webpack.dev.config.js'
}
複製代碼
說明:此處咱們新建一個測試環境的webpack配置文件,用於區分正式環境和測試環境
第三步:配置devServer
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
port: 9999,
contentBase: './dist',
},
plugins: [
]
});
複製代碼
此時,咱們在瀏覽器中輸入:localhost:9999 就能夠訪問到咱們的頁面了。
第四步:實現實時刷新 即,只要代碼改動,保存之後,瀏覽器自動刷新
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
inline: true, //實時刷新
},
plugins: [
]
});
複製代碼
第五步:實現熱更新
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
hot: true, //熱替換
},
plugins: [
// 熱更新插件
new webpack.HotModuleReplacementPlugin()
]
});
複製代碼
注意一下三者的區別:
首先說明一下單頁面和多頁面的區別:
方式1:建立多個入口文件,同時結合 html-webpack-plugin 建立多個html文件,實現多頁面應用
方式2: 使用web-webpack-plugin 插件
說明:此處暫不說明具體配置,你們只需清除單頁面和多頁面的區別,同時,能夠採用一下兩種方式去實現多頁面應用。
經過本節的十幾個實戰場景,相信你們已經基本瞭解了webpack整個配置的機制,什麼場景下采用什麼樣的配置,固然,你們沒必要徹底記住具體的配置,但要知道什麼場景下,用什麼樣的loader或者plugin等, 同時,我的以爲最重要的是 理解這些場景下所蘊含的思想,例如爲何要區分出現單頁面?爲何要分離javascript與css?爲何壓縮文件等等,這些纔是最關鍵的,以後,咱們專門用一節去講述webpack背後所包含的這些思想,你們敬請期待吧!