webpack學習-10天搞定webpack4

 第12天課程-多頁:多入口,匹配多個打包的jscss


const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: {
        home: './src/home.js',
        other: './src/other.js'
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/home.html',
            filename: 'home.html',
            chunks:['home']
        }),
        new HtmlWebpackPlugin({
            template: './src/other.html',
            filename: 'other.html',
            chunks:['other']
        })
    ]
}

 

補充章節:webpack-modehtml


 mode分爲development/production,默認爲production。每一個選項的默認配置以下(common指兩個配置項都存在的屬性):前端

 common:vue

//parent chunk中解決了的chunk會被刪除
optimization.removeAvailableModules:true
//刪除空的chunks
optimization.removeEmptyChunks:true
//合併重複的chunk
optimization.mergeDuplicateChunks:true

 

production node

//性能相關配置
performance:{hints:"error"....}
//某些chunk的子chunk已一種方式被肯定和標記,這些子chunks在加載更大的塊時沒必要加載
optimization.flagIncludedChunks:true
//給常常使用的ids更短的值
optimization.occurrenceOrder:true
//肯定每一個模塊下被使用的導出
optimization.usedExports:true
//識別package.json or rules sideEffects 標誌
optimization.sideEffects:true
//嘗試查找模塊圖中能夠安全鏈接到單個模塊中的段。- -
optimization.concatenateModules:true
//使用uglify-js壓縮代碼
optimization.minimize:true

developmentreact

//調試
devtool:eval
//緩存模塊, 避免在未更改時重建它們。
cache:true
//緩存已解決的依賴項, 避免從新解析它們。
module.unsafeCache:true
//在 bundle 中引入「所包含模塊信息」的相關注釋
output.pathinfo:true
//在可能的狀況下肯定每一個模塊的導出,被用於其餘優化或代碼生成。
optimization.providedExports:true
//找到chunk中共享的模塊,取出來生成單獨的chunk
optimization.splitChunks:true
//爲 webpack 運行時代碼建立單獨的chunk
optimization.runtimeChunk:true
//編譯錯誤時不寫入到輸出
optimization.noEmitOnErrors:true
//給模塊有意義的名稱代替ids
optimization.namedModules:true
//給模chunk有意義的名稱代替ids
optimization.namedChunks:true

 

webpack運行時還會根據mode設置一個全局變量process.env.NODE_ENV,jquery

這裏的process.env.NODE_ENV不是node中的環境變量,而是webpack.DefinePlugin中定義的全局變量,容許你根據不一樣的環境執行不一樣的代碼.webpack

生產環境下,uglify打包代碼時會自動刪除不可達代碼,也就是說生產環境壓縮後最終的代碼爲:es6

 

 

第13天課程-配置source-mapweb


 

安裝依賴

npm install -D babel-loader @babel/core @babel/preset-env 

npm install webpack-dev-server --save-dev

devtool設置項理解,eval 能夠理解爲發射,不是編譯階段產生
  //devtool: 'source-map',//產生文件,能夠顯示行和列
  //devtool: 'eval-source-map',//不實際產生文件,可是能夠顯示行和列
  //devtool: 'cheap-module-source-map',//不顯示列,產生文件
  devtool: 'cheap-module-eval-source-map',//不顯示列,不產生文件

 

試驗代碼src/home.js:

class Demo{
    constructor(){
        console.loga();
    }
}
let d=new Demo();

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: {
    home: './src/home.js',
  },
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist')
  }, 
  //devtool: 'source-map',//產生文件,能夠顯示行和列
  //devtool: 'eval-source-map',//不實際產生文件,可是能夠顯示行和列
  //devtool: 'cheap-module-source-map',//不顯示列,產生文件
  devtool: 'cheap-module-eval-source-map',//不顯示列,不產生文件
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/home.html',
      filename: 'index.html',
      chunks: ['home']
    })
  ]
}

 

 

14章節:watch用法,執行npm run build時候開始


 

更改完代碼以後,當即build,產生編譯文件,

 

"start": "webpack-dev-server",不會產生文件,因此用watch

 

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: {
    home: './src/home.js',
  },
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist')
  }, 
  watch:true,
  watchOptions:{
    poll:1000,//每秒檢查一次變更
    aggregateTimeout:500,//防抖延遲,500秒以後輸入,
    ignored: /node_modules/ //ignored: "files/**/*.js"
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/home.html',
      filename: 'index.html',
      chunks: ['home']
    })
  ]
}

 

 

 

15:webpack小插件介紹

 


 

cleanWebpackPlugin:npm install clean-webpack-plugin -D

關鍵代碼:

const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件
new CleanWebpackPlugin()

官方說明:詳細說明

        /**
         * All files inside webpack's output.path directory will be removed once, but the
         * directory itself will not be. If using webpack 4+'s default configuration,
         * everything under <PROJECT_DIR>/dist/ will be removed.
         * Use cleanOnceBeforeBuildPatterns to override this behavior.
         *
         * During rebuilds, all webpack assets that are not used anymore
         * will be removed automatically.
         *
         * See `Options and Defaults` for information
         */
全部output.path目錄都會被一次刪除,目錄自己不會刪除

 

 

 

copyWebPackPlugin:

 

const CopyWebpackPlugin = require('copy-webpack-plugin'); // 文件拷貝
new CopyWebpackPlugin([{from:'./doc',to:'./'}])

 

bannerPlugin:

let webpack=require('webpack');
new webpack.BannerPlugin('版權全部,違反必究 2019 copyright')

 

 本章節webpack配置文件

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件
const CopyWebpackPlugin  = require('copy-webpack-plugin'); // 引入清除文件插件
let webpack=require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    home: './src/home.js',
  },
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist')
  }, 
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/home.html',
      filename: 'index.html',
      chunks: ['home']
    }),
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin([{from:'./doc',to:'./'}]),
    new webpack.BannerPlugin('版權全部,違反必究 2019 copyright')
  ]
}

 

 16章節:webpack跨域問題


webpack端口默認是8080 若是請求這麼寫,會跨域,跨域是瀏覽器自己的限制,若是使用瀏覽器跨域設置,能夠請求到數據

1:devServer-proxy設置

本地express服務器:localhost:3000/api/user

代理設置:proxy:{'/api':'http://localhost:3000'}

可是不是服務端每一個接口都是api開頭的,因此須要用下面的方式 本地express服務器:localhost:
3000/user 代理devServer設置
  proxy:{
    '/api':{
     target:'http://localhost:3000',
     pathRewrite:{'/api':''}
    }
  }
 

2:單純模擬數據mock 啓動鉤子函數

 

 

3:有服務端,可是不想用代理處理,用express 啓動webpack 端口用express端口

npm install webpack-dev-middleware --save-dev   //安裝依賴
server.js

let express = require('express');
let config=require('./webpack.config');
const webpack = require('webpack');
const middleware = require('webpack-dev-middleware');
const compiler = webpack(config);
let app = express();
app.use(
  middleware(compiler, {
  })
);
app.get('/api/user', (req, res) => {
    res.json({ "name": "珠峯設計-express" });
})
app.listen(3000);

 

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件
const CopyWebpackPlugin = require('copy-webpack-plugin'); // 引入清除文件插件
let webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    home: './src/home.js',
  },
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    before(app) {
      console.log(app);
      app.get('/before', (req, res) => {
        res.json({ "name": "我試mock數據-before" });
      })
    },
    port: 9000,
    /*proxy:{
      '/api':'http://localhost:3000'
    } */
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '/api': '' }//須要先啓動3000端口的服務
      }
    }
  },

  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/home.html',
      filename: 'index.html',
      chunks: ['home']
    }),
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin([{ from: './doc', to: './' }]),
    new webpack.BannerPlugin('版權全部,違反必究 2019 copyright')
  ]
}

 

17:resolve屬性的配置,解析的意思,文件查找別名後綴等配置


 

Webpack 在啓動後會從配置的入口模塊出發找出全部依賴的模塊,Resolve 配置 Webpack 如何尋找模塊所對應的文件。 Webpack 內置 JavaScript 模塊化語法解析功能,默認會採用模塊化標準里約定好的規則去尋找,但你也能夠根據本身的須要修改默認的規則

安裝後模塊:就是會在node_modules裏面Bin裏面有,不須要"/"

模塊目錄指定:

別名:引入bootstrap樣式爲例

 

alias:名稱比較長,可是文件名稱比較長,想取一個短的名字

 

mainFields 可是能不能先找style 再找js mainFields:['style','main'] 字段名稱爲bootstrap裏面package.json key

extensions: 後綴擴展

   默認:extensions: ['.js', '.json']當訪問aa 先找aa.js 再找aa.json若是找不到,報錯

  若是須要typescript須要改爲extensions: ['.ts', '.js', '.json']

  須要css的話,把css加進去

mainFiles:文件名,暫時沒有使用場景

 18:定義環境變量


 把環境變量注入代碼裏面,插件:new webpack.

    new webpack.DefinePlugin({
     'DEV':"'dev'",
     'DevTest':JSON.stringify('devTest'),
     'DevBoolean':true,
     'DevBooleanWithSingle':'true',
     'EXPRESSIONWITHNOTDOT':'1+1',
     'EXPRESSIONWITHDOT':JSON.stringify('1+1'),
    }),

 

輸出結果:

19;區分不一樣環境變量


 

webpack.config.js分開生產和開發環境,

webpack.base.js :公共的

webpack.dev.js 開發的

webpack.prod.js 生產的

安裝插件npm install webpack-merge -D

 

 

webpack.dev.js文件內容 ,這樣咱們就能夠把配置給分開

const { smart } = require('webpack-merge'); const base = require('./webpack.base.js'); module.exports = smart(base, {'mode':'development'})

 

 20:優化設置


 

 新建一個空的工程並安裝插件

npm init -y
npm install webpack webpack-cli html-web
pack-plugin @babel/core babel-loader @babel/preset-env @babel/preset-react jquery -D

>webpack配置裏面的noParse:不解析依賴項

src-index.js文件
import jquery
from 'jquery';

這樣反覆編譯幾回發現,編譯時間是縮短了,我電腦表現大概節約200ms時間

 

 >IgnorePlugin插件:忽略某些模塊,不打包進來

webpack配置裏面exclude include排除目錄(node_modules),包含src 

 安裝moment 時間處理庫:npm insall moment -D

 安裝開發服務器:npm install webpack-dev-server

webpack.config.js文件

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack=require('webpack');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                include:path.resolve("src"),
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env', '@babel/preset-react']
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html',
        }),
        new webpack.IgnorePlugin(/\.\/locale/,/moment/)

    ],
};

index.js

import jquery from 'jquery';
import moment from 'moment';
import 'moment/locale/zh-cn';
moment.locale('zh-cn');//這一句不引入也正確
let r=moment().endOf('day').fromNow();
console.log(r);

 >dllPlugin插件:減小打包體積

安裝npm install react react-dom

 

>happypack多線程打包js,css打包 中間插入一層happypack

>webpack自帶的一些優化,避免沒必要要的tree-shaking,做用域提高scope hosting

生產環境去除沒有用的代碼,開發環境有的,tree-shaking

只有import 管用,require不能夠,es6模塊會把結果放到default對象上

前端推薦import 

webpack會省略一些能夠簡化的代碼

 

25:webpack抽取公共代碼 optimization-splitChunks-cacheGroups裏面配置,多入口文件

 


 

webpack配置文件

optimization:{
splitChunks:{
cacheGroups:{
common:{
chunks:'initial',//抽離階段
minSize:0,抽離大小
minChunks:2//引用多少次就開始抽離

},
vendor:{
priority:1, //避免直接走第一步,不走第二步
test:/node_modules/,
chunks:'initial',
minSize:0,
minChunks;2

}





}
}
}

 

26:懶加載功能webpack


意義:安裝插件@babel/plugin-syntax-dynamic-import 

vue react的路由懶加載實現

button的點擊事件裏面代碼

import('./source.js');

options:{
    presets:['@babel/preset-env','@babel/preset-react'],
    plugins:['@babel/plugin-syntax-dynamic-import ']
}

 

 

 

27:webpack熱更新 開發環境用 默認強制更新,從新編譯


 

devserver:hot:true

兩個插件:webpack.NamedModulesPlugin  /webpack.HotModuleReplacementPlugin

 

index.js

 

import s from './a.js';
if (module.hot) {
    module.hot.accept('./a.js', (s) => {
        let a=import('./a');//
        a.then(function(response){
            console.log(response);
        });
        let b=require('./a.js');
        console.log(b);

    })

}

 

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack=require('webpack');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    devServer:{
     port:3000,
     open:true,
     hot:true,
     contentBase:'./dist'
    },
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                include:path.resolve("src"),
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env', '@babel/preset-react']
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html',
        }),
        new webpack.IgnorePlugin(/\.\/locale/,/moment/),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()

    ],
};

 

28-33:webpack-tapable 同步鉤子和異步鉤子 


 

webpack 本質事件流,主要依賴於發佈訂閱模式

相關文章
相關標籤/搜索