1. 程式人生 > >階段1-第三章-webpack-高階配置(一)

階段1-第三章-webpack-高階配置(一)

1.HTML 中img標籤的圖片資源處理
html-withimg-loader 
只要在html中正常引用圖片即可,webpack會找到對應的資源打包,html裡的img標籤的路徑資源打包,並且把資源重新命名,使用的是url的圖片配置、
  • live-server 在當前資料夾起服務
2.多頁面應用的打包:
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports={
    // 1.修改為多入口
    entry:{
        index:'./src/index.js',
        other:'./src/other.js'
    },
    output:{
        path:path.resolve('/dist'),
        // 2.多入口無法對應一個固定的出口,所以修改filename為[name]變數
        filename:[name].js   //[name] output 這裡可以根據傳入的name 來輸出對應的檔名,index.js和other.js
    },
    plugin:[  // 根目錄下面的index.html是根據html-webpack-plugin 外掛生成的。
                //根據index.html templare 生成的filename index.html
          // 3.如果用了html外掛,需要手動配置多入口對應的html檔案,將制定其對應的輸出檔案      
        new HtmlWebpackPlugin({
            filename:'index.html',
            template:'./src/index.html',
            chunks:['index','main']  // 只引入要新增的chunks
        }),
        new HtmlWebpackPlugin({
            filename:'other.html',
            template:'./src/other.html',
            chunks:['other']   
        })
    ]    
}
3. 第三方庫的兩種引入方式
   // 可以掛載多個全域性變數
可以通過 expose-loader 進行全域性變數的注入,同時也可以使用內建外掛webpack.ProvidePlugin 對每個模組的閉包空間,注入一個變數,制動載入模組,而不用匯出import 或 require

expose-loader    全域性變數   //  通常和第三方庫結合使用時會用到,因為第三方庫回去尋找全域性jquery變數
npm i expose-loader -D
webpack.ProvidePlugin
4.development和production不同配置檔案的打包
webpack-merge
npm i webpack-merge -D
    webpack.base.js
    webapck.prod.js   // 優化配置,程式碼拆分,程式碼壓縮,加密
    webpack.dev.js
步驟如下:
-   將開發環境和生產環境公用的配置放入base中,不同的配置各自放入prod和dev中 
-   然後在dev和prod中使用webpack-merge 把自己的配置與base的配置進行合併並匯出
-  將 package.json中的指令碼引數進行修改,通過--config手動指定特定的配置檔案

webpack.dev.js

 const merge  = require('webpack-merge');
 const baseConfig =  require('./webpack.base.js')
 module.exports = merge(baseConfig,{
     mode:'developlment'
     devServer:{
         open:true,
         hot: true,
         compress: true,
         port: 3000,
        proxy:{
            '/api': {
                target: "http://localhost:9999",
                pathRewrite: {
                    // 轉發請求時不會攜帶 '/api'
                    // 實際請求的是http://localhost:9999/getUserInfo
                    '^/api': ''
                }
            }
           
        } 
     }
 })

package.json

{
    "script":{
        "test": 'echo',
        "buildcustom":"webpack --config webpack.custom.config.js",
        "build":"webpack --config ./build/webapck.prod.js",
        "dev":"webpack-dev-server --config ./build/webpack.dev.js",
        "server": "node server.js",
        "start": "live-server ./dist"  //用live-server 開啟dist資料夾,啟動小型伺服器
    }
}
定義build資料夾,將 webpack.base.js, webpack.prod.js, webpack.dev.js 放入build資料夾
此時在output路徑拼接需要使用:
output:{
    //相對路徑都是相對的專案根目錄,絕對路徑是當前檔案所在的的絕對路徑記得往上翻一層
    path:path.resolve(__dirname,'..','./dist/')
},
plugins:[
    new CopyWebpackPlugin({
        from: path.join(__dirname,'..','assets'),
        to: 'assets'
    })
]
5. 定義環境變數
  webpack 內建外掛  webpack.DefinePlugin({})  
  DefinePlugin 會解析定義的環境變量表達式,這裡的值會當成變數來處理
 此環境變數都可以在src打包的資料夾下面使用
let host = 'http://192.168.1.22:8080'
if(is_dev){
    host = 'www.newbaker.cn:9999'
}
6. 使用devServer 解決跨越問題

  • 由於開發時會用到webpack-dev-server ,所以一定會產生跨域問題
  • jsonp (淘汰)
  • cors 跨域資源共享
  • http proxy

http代理

  • 其原理就是將所有請求發給devServer,再由devServer伺服器做一次轉發,傳送給資料介面伺服器;
  • 由於ajax是傳送給devServer伺服器的,所以不存在跨域,而devServer是用node平臺傳送的http請求,自然也不涉及跨域問題

node中使用CORS:
npm i cors --save-dev
app.js
const express = require('express')
const app = express()
const cors = require('cors')  //加上了響應頭  responese Headersd   Access-Control-Allow-Origin: *
app.use(cors())
app.get('/api/getUserInfo',(req,res) => {
    res.send({
        name:'wjx',
        age: 18
    })
})
app.listen(9999, () => {
    console.log('http://localhost:9999')
})
7 HMR 熱更新
hot module reload   // 不適用於生產環境,只是在開發環境
module.hot.accept('./hotModule.js',()=>{
    // import 和 export 必須在頂級作用域使用
    var str = require('./hotModule.js)
})

以上用到的配置webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const path = require('path')
module.exports={
 entry: './src/main.js',
 output:{
//必須為絕對路徑
//path.resolve() 解析當前路徑的絕對路徑
// path.join(__dirname,'./dist/')
path: path.resolve("./dist/"),
filename: 'bundle.js'
},
  mode:'development'  //不設定預設為production ,
//  watch: true,   //開啟監視模式,自動編譯,生成輸出檔案
devServer:{
    open: true,
    port: 5000,
    hot: ture,
    compress: true,
    contentBase: '/src',   
    },
 plugins:[
 //外掛一般引入進來是個建構函式
 //根據模板'/src/indtx.html'生成檔案'index.html'
     new HtmlWebpackPlugin({
         filename:'index',
         template:'./src/index.html'
     }),
     new CleanWebpackPlugin(),
     new CopyWebpackPlugin([{
         from: path.join(__dirname,'assets'),
         to:'assets'
     },
     {
         from: path.join(__dirname,'image'),
         to:'image'
     }
     ]),
     new webpack.BannerPlugin('可以為每個chunk檔案頭部新增banner'),
     new webpack.ProvidePlugin({  // 內建外掛,在每個模組內部掛載一個jQuery
         $:'jquery',
         jQuery:'jquery'
     }),
     new webpack.DefinePlugin({
         IS_DEV: 'true',
         test1: '"1+1"'  //這裡的值會當成變數來處理,所以裡面要用“” 拼接
     })
 ],
 module:{
     rules:[
         {
             test:/\.css$/,
             // webapck 讀取loader時 是從左到右讀取,會將css檔案先交給最右側的loader
             // loader的執行順序是從右到左以管道的方式鏈式呼叫
             // css-loader:解析css,使其支援css語法格式
             // style-loader: 將解析出來的結果放到 html中,使其生效
             use:['style-loader','css-loader']
         },
         {
             test:/\.less$/,
             //less-loader 只是將less檔案轉成css語法
             use:['style-loader','css-loader','less-loader']
         },
         {
             test:/\.s(a|c)ss$/,
             use:['style-loader','css-loader','sass-loader']
         },
         {
             test:/\.jpg|jpeg|png|gif|bmp$/,
             use:['file-loader']
         },
         {
             test:/\.(woff|woff2|eot|svg|ttf)$/,
             use:['file-loader']
         },
         {
             test:/\.(jpg|jpeg|png|gif|bmp)$/,
             use:{
                 loader:'url-loader',
                 options:{
      /* url-loader功能*/  limit:5*1024,   //5kb  如果圖片大小  小於5kb直接轉成base64
        /* file-loader功能*/  outputPath:'images',
       /* file-loader功能*/  name:[name]-aaa[hash:4].[ext]  //ext副檔名 -中間可以加常量,hash:4 保留4位hash值
                 }
             }
         },
         {
             test:/\.js$/,
             use:{
                 loader:'babel-loader',
                 options:[
                     presets:['@babel/env'],
                     plugins:[
                     '@babel/plugin-proposal-class-properties',
                     '@babel/plugin-transform-runtime'
                     ]
                 ]
             },
             exclude:/node_modules/
         },
         {
           test:/\.(html|htm)$/i,
           user{
                loader:'html-withimg-loader'  
           }
         },
         {
             // 用於解析JQuery模組的絕對路徑
             test:require.resolve('jquery'),  // node_modules/jquery/pacakge.json  > main
             use:{
                 loader:'expose-loader',
                 options: '$'   // 將引入的jquery掛載到了全域性$
             }
         }
     ]
 },
 devtools:'cheap-module-eval-sourc