Webpack4.x 學習過程

前言

以前一直據說 webpack 的大名,惋惜不曾得見。今天有空,初步瞭解了 Webpack 工做方式後,一步步的開始學習使用 Webpack,並把其中的關鍵點記錄下來css

這不是一個教程,是工做當中用到的時候才寫的,全部看起來會有點亂

環境配置

  • 須要用到 node 環境,建議依賴node的環境版本>=6.11.5
  • 進入項目初始化 npm init,生成package.json
  • 正常安裝 webpack 以外,webpack4 須要再單獨安一個 webpack-cli

    npm init
    npm install --save-dev webpack webpack-clihtml

webpack.config.js

一、建立 webpack.config.js

let path = require('path');
let webpack = require('webpack');

module.exports = {
    mode: "development", // 模式配置 development || production
    entry: '',               // 入口文件
    output: {},              // 出口文件
    module: {},              // 處理對應模塊
    plugins: [],             // 對應的插件
    devServer: {},           // development  下開發服務器
}

二、啓動靜態服務器

若是文件被更新,代碼將被從新編譯node

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

// webpack.config.js
devServer: {
    contentBase: './dist', // 靜態文件根目錄
    hot: true, // 模塊熱替換
    overlay: true, // 瀏覽器頁面上顯示錯誤
    stats: "errors-only", // 控制編譯的時候shell上的輸出內容  minimal || normal || verbose
    compress: true // 服務器返回瀏覽器的時候是否啓動gzip壓縮
},
module.exports = {
    plugins: [
        new webpack.NamedModulesPlugin(),
        // 熱替換,熱替換不是刷新
        new webpack.HotModuleReplacementPlugin()
    ],
}

//package.json
"start": "webpack-dev-server --open",

js中的內容修改保存後,在不刷新頁面的狀況下直接修改掉,這樣就實現了熱更新react

三、Source Maps 調試

開發中方便的調試能極大的提升開發效率,不過經過打包後的文件,很難找到出錯了的地方,Source Maps 就是來幫咱們解決這個問題的webpack

// webpack.config.js
devtool: 'inline-source-map' // 有多種選項

四、Html模板和清空 dist

使用hash值以後,每次打包的文件都不同,dist裏面的文件會愈來愈多,須要每次打包前清空文件夾
文件都打包好了,可是咱們在使用的時候不能在dist目錄下去建立一個html文件,而後去引用打包後的js吧,這不合理,實際開發中也不會這樣
咱們須要實現html打包功能,能夠經過一個模板實現打包出引用好路徑的html來git

npm install --save-dev html-webpack-plugin clean-webpack-plugin 

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
       template: path.resolve(__dirname, 'app', 'index.tmpl.html'),// 源模板文件
        filename:'index.html',  //生成的html存放路徑,相對於 path
        minify:{  //壓縮HTML文件
            removeComments:true,  //移除HTML中的註釋
            collapseWhitespace:false  //刪除空白符與換行符
        },
        //chunks:['index', 'vendor'], // 多入口的html文件用chunks這個參數來區分
    })
]

五、多入口文件

entry: {
        index: './src/index.js',
        login: './src/login.js'
    },
    output: {
        // [name]就能夠將出口文件名和入口文件名一一對應
        filename: '[name]-[hash].js',      // 打包後會生成index.js和login.js文件
        path: path.resolve('dist')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',   
            filename: 'index.html',
            chunks: ['index']   // 對應關係,index.js對應的是index.html
        }),
        new HtmlWebpackPlugin({
            template: './src/login.html',
            filename: 'login.html',
            chunks: ['login']   // 對應關係,login.js對應的是login.html
        })
    ]

六、加載 CSS

css文件須要額外的loader支持github

npm install --save-dev style-loader css-loader

// webpack.config.js    
  module.exports = {
   module: {
     rules: [
       {
         test: /\.css$/,
         use: [  // 從右向左解析
           'style-loader',
           'css-loader'
         ]
       }
     ]
   }
  };
  
// 在入口文件 main.js 加入:
import './style.css';

打包後的css文件是以行內樣式style的標籤寫進打包後的html頁面web

七、拆分 css

所有打包到一個文件,太多會影響加載速度,須要把文件拆分shell

npm install --save-dev mini-css-extract-plugin

 // webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // CSS文件單獨提取出來

module: { 
    rules: [
        {
            test: /\.css$/,
            use: [
                // 將 css 用 link 的方式引入就再也不須要 style-loader
                MiniCssExtractPlugin.loader,
                "css-loader"
            ],
            include: path.resolve(__dirname, 'app'), // 限制範圍,提升打包速度
            exclude: /node_modules/
        },
    ]
}

new MiniCssExtractPlugin({
    filename: `css/[name]-[contenthash].css`,
}),

添加 CSS3 前綴
經過 postcss 中的 autoprefixer 能夠實現將 CSS3 中的一些須要兼容寫法的屬性添加響應的前綴,這樣省去咱們很多的時間npm

npm install --save-dev postcss-loader autoprefixer

在項目根目錄下建立一個 postcss.config.js 文件

// postcss.config.js
module.exports = {
    plugins: [require('autoprefixer')]  // 引用該插件便可了
}

// webpack.config.js 
{
    test: /\.css$/,
    use: ['style-loader', 'css-loader', 'postcss-loader']
}

八、加載圖片

npm install --save-dev file-loader url-loader

// webpack.config.js  
module: {
  rules: [
   {
        test: /\.(png|svg|jpg|gif)$/,
        //use: ['file-loader']
        use: [
            {
                // url-loader內置了file-loader
                loader: 'url-loader',
                options: {
                    limit: 8192,    // 小於8k的圖片自動轉成base64格式,而且不會存在實體圖片
                    outputPath: 'images/'   // 圖片打包後存放的目錄
                }
            }
        ]
    },
  ]
 ]
 
// main.js
import Icon from './icon.png';

頁面中常常會用到img標籤,img引用的圖片地址也須要一個loader來幫咱們處理好

npm install --save-dev html-withimg-loader
module.exports = {
    module: {
        rules: [
            {
                test: /\.(htm|html)$/,
                use: 'html-withimg-loader'
            }
        ]
    }
}

這樣再打包後的html文件下img就能夠正常引用圖片路徑了

svg圖片均可以經過file-loader來解析,樣式中引入了這類格式的圖標或者圖片都沒有問題了,img若是也引用svg格式的話,配合上面寫好的html-withimg-loader就都沒有問題了

九、加載字體

file-loader 和 url-loader 能夠接收並加載任何文件,而後將其輸出到構建目錄

// webpack.config.js
 {
     test: /\.(woff|woff2|eot|ttf|otf)$/,
     use: [
       'file-loader'
     ]
   }
   
// style.css
@font-face {
    font-family: 'MyFont';
    src:  url('./Omnes_Light.otf') format('woff2');
    font-weight: 600;
    font-style: normal;
}

十、加載數據

NodeJS,JSON 支持其實是內置
導入 CSV、TSV 和 XML

npm install --save-dev csv-loader xml-loader

//webpack.config.js
{
    test: /\.(csv|tsv)$/,
    use: [
        'csv-loader'
    ]
},
{
    test: /\.xml$/,
    use: [
        'xml-loader'
    ]
}

// main.js
// 所導入的 Data 變量將包含可直接使用的已解析 JSON
import Data from './data.xml'; // JSON, CSV, TSV, XML

十一、模塊熱替換

css的hash命名必須使用contenthash,保證即便css文件所處的模塊裏就算其餘文件內容改變,只要css文件內容不變,那麼不會重複構建

css 若是使用style-loader將樣式添加到js文件中,在編寫樣式的時候能夠享受熱更新的效果,若是將樣式提取,須要手動刷新。

方法二:在入口文件中引入html文件,並使用raw-loader對html文件進行處理,實現html熱更新

html自動更新
一、安裝raw-loader

npm install --save-dev raw-loader

二、在webpack.config.js中配置raw-loader

rules: [  
      ......  
      {  
         test: /\.(htm|html)$/,  
         use: [  
           'raw-loader'  
         ]  
      }  
      ......  
    ]

三、在入口文件index.js文件中引入index.html文件

import '../template/index.html'

十二、轉義 ES6

在實際開發中,常用 ES6 去寫代碼,這樣會提升咱們寫代碼的速度,不過爲了向後兼容低版本瀏覽器,須要 Babel 轉換成兼容的代碼

npm install -save-dev babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react

代碼不只僅包含ES6還有以後的版本和那些僅僅是草案的內容,因此咱們能夠經過一個.babelrc文件來配置一下

// .babelrc
{
    "presets": ["env", "stage-0"]   // 從右向左解析
}

// webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test:/\.js$/,
                use: 'bable-loader',
                include: /src/,          // 只轉化src目錄下的js
                exclude: /node_modules/  // 排除掉node_modules,優化打包速度
            }
        ]
    }
}

1三、構建開發和生產環境-分離配置文件

npm install --save-dev webpack-merge

新建 webpack.common.js、webpack.dev.js、webpack.prod.js
把 webpack.config.js 文件內容分爲公共代碼、開發代碼、生產代碼

1四、壓縮提取出的css,解決分離出的js重複問題

npm install --save-dev optimize-css-assets-webpack-plugin

// webpack.prod.js
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');

plugins: [
        new OptimizeCSSPlugin({
            cssProcessorOptions: {safe: true}
        }),
    ]

1五、集中拷貝靜態資源

npm install --save-dev copy-webpack-plugin

// webpack.prod.js
const copyWebpackPlugin = require('copy-webpack-plugin');

new copyWebpackPlugin([{

from:__dirname+'/src/public',//打包的靜態資源目錄地址
to:'./public' //打包到dist下面的public

}]),

1六、報錯

一、Cannot use [chunkhash] or [contenthash] for chunk in '[name]-[chunkhash].js' (use [hash] instead)
解決方法:

  • 若是是開發環境,將配置文件中入口文件的 chunkhash 替換爲 hash
  • 若是是生產環境,不要使用參數 --hot

二、Refusing to install package with name "react" under a package also called "react".
解決方法:package.json name 的值不能跟npm的包名相同,同時把 package-lock.json 的 name 修改

三、img 和 css 的圖片路徑不對
若是是在css文件裏引入的如背景圖之類的圖片,就須要指定一下相對路徑

module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            /*
                            * 複寫 css 文件中資源路徑
                            * 由於 css 文件中的外鏈是相對與 css 的,
                            * 咱們抽離的 css 文件在可能會單獨放在 css 文件夾內
                            * 引用其餘如 img/a.png 會尋址錯誤
                            */
                            publicPath: '../' 
                        }
                    },
                    { loader: "css-loader" },
                    { loader: "postcss-loader" }
                ],
                include: path.resolve(__dirname, 'src'),
                exclude: /node_modules/
            }
        ]
    }

異常狀況

這是 webpack4 的一些常規操做 Github
官網

相關文章
相關標籤/搜索