2.webpack配置和筆記

相關的源碼地址:https://github.com/zqdeveloper/webpack

1.打包樣式資源

  1. loader名稱: css-loader和style-loader、less、less-loader
  2. 安裝方式: npm i css-loader style-loader less less-loader -D
  3. 配置方式:
{
  //匹配哪些文件
  test:/\.css$/,
  //使用哪些loader進行處理
  use:[
      //use數(shù)組中l(wèi)oader執(zhí)行順序,從右到左 從下到上 依次執(zhí)行
      //創(chuàng)建style標簽將js中的樣式資源插入進去,添加到head中生效
      'style-loader',
      //將css文件一字符串的形式變成一個commonjs模塊加載到js中,里面內(nèi)容是樣式字符串
      'css-loader'
  ]
},
{
  test:/\.less$/,
  use:[
      'style-loader',
      'css-loader',
      'less-loader'
  ]
},

2. 打包HTML資源

  1. 插件名稱:html-webpack-plugin
  2. 安裝命令: npm i html-webpack-plugin -D
  3. 插件引入:
    const HtmlWebpackPlugin = require('html-webpack-plugin')
  4. 插件配置:
  new HtmlWebpackPlugin({
      //復制‘./src/index.html’文件,并自動引入打包輸出的所有資源
      template:'./src/index.html'
  }),

3. 打包圖片資源

  1. 處理圖片
    1.1 loader: url-loader和file-loader
    1.2 安裝命令: npm i url-loader file-loader -D
    1.2 配置方式:
{
     test:/\.(jpg|png|gif)$/,
     //下載url-loader file-loader
     loader: 'url-loader',
     options:{
         //圖片大小小于8kb,就會被base64處理
         //優(yōu)點:減少請求數(shù)量(減輕服務器壓力)
         //缺點: 圖片體積會更大,(文件請求速度更慢)
         limit:8*1024,
         //問題:因為url-loader默認使用es6模塊化解析,而html-loader引入圖片是commonjs
         //解析時會出問題:[object module]
         //解決:關閉url-loader的es6模塊化,使用commonjs解析
         esModel:false,
         //[hash:10]取圖片的hash的前10位
         //ext:取文件原來的擴展名
         name:'[hash:10].[ext]'
     }
},
  1. 處理html中的img引用的圖片資源
    2.1 loader名稱:html-loader
    2.2 安裝命令: npm i html-loader -D
    2.2 配置方式:
{
    test:/\.html$/,
    //處理html文件的img圖片(負責引入img,從而能被url-loader進行處理)
    loader:'html-loader'
}

4.打包其它資源

  1. loader名稱: file-loader
  2. 安裝命令: npm i file-loader -D
  3. 配置方式:
{
   //打包其它資源(除了html/js/css資源以外的資源)
   exclude:/\.(css|js|html)$/,
   loader:'file-loader',
   options:{
       name:'[hash:4].[ext]'
   }
}

5. DevServer

  1. 插件: webpack-dev-server
  2. 安裝命令: npm i webpack-dev-server -D
  3. 配置方式:
//開發(fā)服務器devServer:用來自動化(自動編譯,自動打開瀏覽器,自動刷新瀏覽器)
//特點:只會在內(nèi)存中編譯打包,不會有任何輸出
//啟動devServer指令為:npx webpack-dev-server
devServer:{
    //項目路徑
    contentBase:resolve(__dirname,'build'),
    //啟動gzip壓縮
    compress:true,
    //端口號
    port:3000,
    //自動打開瀏覽器
    open:true,
}

6. 開發(fā)環(huán)境配置:

const {resolve} = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
module.exports = {
    entry:'./src/js/index.js',
    output:{
        filename:'js/built.js',
        path:resolve(__dirname,'build'),
    },
    module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test:/\.less$/,
                use:[
                    'style-loader',
                    'css-loader',
                    'less-loader',
                ]
            },
            {
                test:/\.(gif|png|jpg)$/,
                loader:'url-loader',
                options:{
                    limit:8*1024,
                    esModel:false,
                    name:'[hash:10].[ext]',
                    outputPath:"imgs"
                }
            },
            {
                test:/\.html$/,
                loader:'html-loader'
            },
            {
                exclude:/\.(less|gif|png|jpg|html|css|js)$/,
                loader:'file-loader',
                options:{
                    name:'[hash:10].[ext]',
                    outputPath:"media"
                }
            }
        ]
    },
    plugins:[
        new HtmlWebPackPlugin({
            template:'./src/index.html',
        })
    ],
    mode:'development',
    devServer:{
        contentBase:resolve(__dirname,'build'),
        compress:true,
        port:3000,
        open:true
    }
}

7. 提取css成單獨文件

  1. 插件名成: mini-css-extract-plugin
  2. 安裝命令: npm i mini-css-extract-plugin
  3. 插件引入: const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  4. 插件配置:
 new MiniCssExtractPlugin({
    //打包名稱和路徑
    filename:'css/built.css'
}),
  1. 同時修改loader中的style為MiniCssExtractPlugin的loader,如下:
 module:{
    rules:[
        {
            test:/\.css$/,
            use:[
                MiniCssExtractPlugin.loader,
                //'style-loader',
                'css-loader'
            ]
        },
        {
            test:/\.less$/,
            use:[
                //'style-loader',
                MiniCssExtractPlugin.loader,
                'css-loader',
                'less-loader'
            ]
        },
    ]
},

8. css兼容性處理

  1. loader名稱: postcss-loader
  2. 安裝命令: npm i postcss-loader -D
  3. 需要結合css loader一起使用
  4. 配置方式:
{
    test:/\.css$/,
    use:[
        MiniCssExtractPlugin.loader,
        //'style-loader',
        'css-loader',
        /**
         * css兼容性處理:postcss-->postcss-loader postcss-preset-env
         * 
         * 幫助postcss找到package.json中brewlist里面的配置,通過配置加載指定的css兼容性樣式
         * 
         *  "browserslist":{
         *      //開發(fā)環(huán)境-->設置node環(huán)境變量:process.env.NODE_ENV = development
                "development":[
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
                ],
                "production":[
                ">0.2%",
                "not dead",
                "not_op_mini all"
                ]
            }
         */
        //使用loader的默認配置
        //‘postcss-loader’
        {
            loader:'postcss-loader',
            options:{
                ident:'postcss',
                plugins: () => [
                    //postcss的插件
                    require('postcss-preset-env')()
                ]
            }
        }
    ]
},
  1. 同時需要在packages.json中增加的配置如下:
 "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }
  1. 要使其在開發(fā)環(huán)境中生效,需要設置node環(huán)境為developement,在webpack.config.js中設置:
  process.env.NODE_ENV = 'development'

9. 壓縮css

  1. 所用的插件: optimize-css-assets-webpack-plugin
  2. 安裝命令: npm i optimize-css-assets-webpack-plugin -D
  3. 插件引入: const OptimizeCssAssetsWebpaclPlugin = require('optimize-css-assets-webpack-plugin')
  4. 配置方式::
  new OptimizeCssAssetsWebpaclPlugin()

10. js語法檢查

  1. 插件名稱: eslint-loader、eslint 、eslint-config-airbnb-base 、 eslint-plugin-import
  2. 安裝命令: npm i eslint eslint-loader eslint-config-airbnb-base eslint-plugin-import -D
  3. 配置:
    3.1 規(guī)則中使用:
 /**
  * 語法檢查: eslint-loader ,eslint-loader依賴eslint
  *  注意:只檢查自己寫的源代碼,第三庫是不用檢查的
  *  設置檢查規(guī)則: 
  *   package.json中eslintConfig中配置
  *       airbnb --> eslint-config-airbnb-base eseslint-plugin-import
  */
 {
      test: /\.js$/,
      loader: 'eslint-loader',
      exclude: /node_modules/,//排除node_modules
      options: {
          fix: true
      }
 }

3.2 在package.json中增加:

"eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  }

11.js 兼容性處理

  1. 所用的loader: babel-loader @babel/preset-env @babel/core
  2. 安裝命令: npm i babel-loader @babel/preset-env @babel/core -D
  3. 配置:
/**
 * js兼容性處理: babel-loader @babel/preset-env @babel/core
 *      1. 基本js兼容性處理---> @bebel/preset-env
 *             問題: 只能轉換基本語法,如promise不能轉換
 *      2. 全部js兼容性處理--> @babel/polyfill
 */
{
    test:/\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
        //預設 :babel做怎么樣的兼容性處理
        presets: ['@babel/preset-env']
    }
}
  1. @babel/polyfill 的使用
  2. 下載: npm i @babel/polyfill -D
  3. 引用: 在入口js源代碼里面使用import 引入:
    import '@babel/polyfill'
    問題: 我只需要解決部分兼容性問題,但是會把所有的兼容性處理全部引入,體積太大
  4. 按需加載 需要做兼容性處理的就做: 按需加載 ---> core-js
    7.1 安裝:npm i core-js -D
    7.2 配置:
{
    test:/\.js$/,
    loader: 'babel-loader',
    exclude: /node_modules/,
    options: {
        //預設 :babel做怎么樣的兼容性處理
        // 預設:指示babel做怎么樣的兼容性處理
        presets: [
          [
            '@babel/preset-env',
            {
              // 按需加載
              useBuiltIns: 'usage',
              // 指定core-js版本
              corejs: {
                version: 3
              },
              // 指定兼容性做到哪個版本瀏覽器
              targets: {
                chrome: '60',
                firefox: '60',
                ie: '9',
                safari: '10',
                edge: '17'
              }
            }
          ]
        ]
    }
}

12.js壓縮

只需要把mode修改為production即可

13.html壓縮

使用HtmlWebpackPlugin即可,如下:

new HtmlWebpackPlugin({
    template: './src/index.html',
    minify:{
      //移出空格
      collapseWhitespace: true,
      //移除注釋
      removeComments: true
    }
})

14. 生產(chǎn)環(huán)境配置

const {resolve} = require('path')

const HtmlWebPackPlugin =  require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpaclPlugin  = require('optimize-css-assets-webpack-plugin')
//定義nodejs的環(huán)境變量:決定使用browserslist的哪個環(huán)境
process.env.NODE_ENV = 'development';
//復用loader
const commonCssLoader = [
    MiniCssExtractPlugin.loader,
    'css-lodaer',
    {
        //還需要在package.json中定義browserslist
        loader: 'postcss-loader',
        options: {
            ident: 'postcss',
            plugins: () => [
                require('postcss-preset-env')()
            ]
        }
    }
]
module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/built.js',
        path: resolve(__dirname,'build')
    },
    module: {
        rules:[
            {
                test:/\.css$/,
                use: [...commonCssLoader]
            },
            {
                test: /\.less$/,
                use: [...commonCssLoader,'less-loader']
            },
            //正常來講,一個文件只能被一個loader處理;
            //當一個文件要被多個loader處理,那么一定要指定loader的執(zhí)行先后順序;
            // 先執(zhí)行eslint再執(zhí)行babel
            {
                //在package.json中來添加eslintConfig --> airbnb
                test:/\.js$/,
                exclude: /node_modules/,
                loader: 'eslint-loader',
                //優(yōu)先執(zhí)行
                enforce:'pre',
                options: {
                    fix: true
                }
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets:[
                        [
                            '@babel/preset-env',
                            {
                                useBuiltIns:'usage',
                                corejs: {version:3},
                                targets: {
                                    chrome: '60',
                                    firefox: '50'
                                }
                            }

                        ]
                    ]
                }
            },
            {
                test:/\.(jpg|png|gif)$/,
                loader: 'url-loader',
                options: {
                    limit: 8*1024,
                    //使用來html-loader一定要關閉url-loader的esModel
                    esModule: false,
                    name: '[hash:10].[ext]',
                    outputPath: 'imgs'
                }
            },
            {
                test: /\.html$/,
                loader: 'html-loader',
            },
            {
                exclude:/\.(js|css|less|html|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                    outputPath: 'media'
                }
            }
        ]
    },
    plugins:[
        new HtmlWebPackPlugin({
            template: './src/index.html',
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        }),
        new MiniCssExtractPlugin({
            filename:'css/built.css'
        }),
        new OptimizeCssAssetsWebpaclPlugin()
    ],
    mode: 'production'
}

15. 開發(fā)環(huán)境優(yōu)化


/**
 * HMR: hot module replacement 熱模塊替換/模塊熱替換
 *  作用: 一個模塊發(fā)生變化,只會重新打包這一個模塊(而不是打包所有模塊)
 *      極大提升構建速度
 *      
 *      樣式文件 :可以使用HMR功能:因為style-loader內(nèi)部實現(xiàn)了~
 *      js文件:默認沒有HMR功能--->需要修改js代碼,添加支持HMR功能的代碼
 *             注意:HMR功能對js的處理,只能處理非入口js文件的其它文件
 *      HTML文件: 默認也不能使用HMR功能,同時導致HTML不能熱更新了~(不用做HMR功能)
 *              解決: 修改entry入口,入口html也引入
 */
const {resolve} = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
module.exports = {
    entry: ['./src/js/index.js','./src/index.html'],
    output:{
        filename:'js/built.js',
        path:resolve(__dirname,'build'),
    },
    module:{
        rules:[
            {
                test:/\.css$/,
                use:[
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test:/\.less$/,
                use:[
                    'style-loader',
                    'css-loader',
                    'less-loader',
                ]
            },
            {
                test:/\.(gif|png|jpg)$/,
                loader:'url-loader',
                options:{
                    limit:8*1024,
                    esModel:false,
                    name:'[hash:10].[ext]',
                    outputPath:"imgs"
                }
            },
            {
                test:/\.html$/,
                loader:'html-loader'
            },
            {
                exclude:/\.(less|gif|png|jpg|html|css|js)$/,
                loader:'file-loader',
                options:{
                    name:'[hash:10].[ext]',
                    outputPath:"media"
                }
            }
        ]
    },
    plugins:[
        new HtmlWebPackPlugin({
            template:'./src/index.html',
        })
    ],
    mode:'development',
    devServer:{
        contentBase:resolve(__dirname,'build'),
        compress:true,
        port:3000,
        open:true,
        //開啟HMR功能
        //當修改了webpack配置,新配置要想生效,必須要重啟webpack服務
        hot: true
    }
}

16.source-map

source-map: 一種提供源代碼到構建后代碼映射技術(如構建后代碼出錯了,通過映射關系可以追蹤源代碼的錯誤)
[inline-|hidden-|eval-][nosources-][cheap-[module-]]souce-map

inline-source-map: 內(nèi)聯(lián)
    只生成一個內(nèi)聯(lián)source-map
    錯誤代碼準確信息和源代碼準確位置

hidden-source-map: 外部
    能夠提示到錯誤的錯誤原因,但是沒有錯誤位置,不能追蹤到源代碼的錯誤,只能提示到構建后代碼的錯誤位置

eval-source-map: 內(nèi)聯(lián),
    每一個文件都生成對應的source-map,都在eval
    錯誤代碼準確信息和源代碼準確位置
    多了一個hash值

nosources-source-map: 外部
    能夠提示到錯誤的錯誤原因,但是沒有任何源代碼信息

cheap-source-map: 外部
    錯誤代碼準確信息和源代碼準確位置,但是錯誤位置只精確到行,不精確到列

cheap-module-source-map: 外部
    錯誤代碼準確信息和源代碼準確位置,但是錯誤位置只精確到行,不精確到列
    會將loader和source map加入

source-map:外部
    錯誤代碼準確信息和源代碼準確位置

內(nèi)聯(lián)和外部的區(qū)別:1.外部生成了文件,內(nèi)聯(lián)是沒有的;2.內(nèi)聯(lián)構建速度更快

開發(fā)環(huán)境:速度快,調(diào)試更友好
    速度快(eval>inline>cheap>...)
        eval-cheap-source-map
        eval-source-map
    調(diào)試更友好
        source-map
        cheap-module-source-map
        cheap-source-map
    
        -->eval-source-map /eval-cheap-module-sourcemap
生產(chǎn)環(huán)境:源代碼要不要隱藏?調(diào)試要不要更友好
    內(nèi)聯(lián)會讓代碼體積非常大,所以再生產(chǎn)環(huán)境不用內(nèi)聯(lián)
    nosources-source-map 全部隱藏
    hidden-source-map   只隱藏源代碼,會提示構建后代碼錯誤

    -->source-map /cheap-module-source-map

17. oneof

在roles種使用oneof,需要注意事項:

  • 一下loader只會匹配一個
  • 注意:不能讓兩個loader處理同一種類型的文件
  • 正常來講,一個文件只能被一個loader處理;
  • 當一個文件要被多個loader處理,那么一定要指定loader的執(zhí)行先后順序;
  • 先執(zhí)行eslint再執(zhí)行babel
    代碼如下:
rules:[
     {
         //在package.json中來添加eslintConfig --> airbnb
         test:/\.js$/,
         exclude: /node_modules/,
         loader: 'eslint-loader',
         //優(yōu)先執(zhí)行
         enforce:'pre',
         options: {
             fix: true
         }
     },
     {
         //一下loader只會匹配一個
         //注意:不能讓兩個loader處理同一種類型的文件
         oneof: [
             {
                 test:/\.css$/,
                 use: [...commonCssLoader]
             },
             {
                 test: /\.less$/,
                 use: [...commonCssLoader,'less-loader']
             },
             //正常來講,一個文件只能被一個loader處理;
        /當一個文件要被多個loader處理,那么一定要指定loa  行先后順序;
             // 先執(zhí)行eslint再執(zhí)行babel
             {
                 test: /\.js$/,
                 exclude: /node_modules/,
                 loader: 'babel-loader',
                 options: {
                     presets:[
                         [
                             '@babel/preset-env',
                             {
                                 useBuiltIns:'usage',
                                 corejs: {version:3},
                                 targets: {
                                     chrome: '60',
                                     firefox: '50'
                                 }
                             }
  
                         ]
                     ]
                 }
             },
             {
                 test:/\.(jpg|png|gif)$/,
                 loader: 'url-loader',
                 options: {
                     limit: 8*1024,
                /使用來html-loader一定要關閉url-loader的e l
                     esModule: false,
                     name: '[hash:10].[ext]',
                     outputPath: 'imgs'
                 }
             },
             {
                 test: /\.html$/,
                 loader: 'html-loader',
             },
             {
                 exclude:/\.(js|css|less|html|jpg|png|gif)$/,
                 loader: 'file-loader',
                 options: {
                     outputPath: 'media'
                 }
             }
         ]
     }
]

18.緩存

  1. 在babel-loader中開啟緩存
{
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
        presets:[
            [
                '@babel/preset-env',
                {
                    useBuiltIns:'usage',
                    corejs: {version:3},
                    targets: {
                        chrome: '60',
                        firefox: '50'
                    }
                }
        
            ]
        ],
        //開啟babel緩存
        //第二次構建時,會讀取之前的緩存
        cacheDirectory: true
    }
},
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372