webpack踩坑記錄

最近在學習webpack的一些配置,學習的指望就是經過能夠經過webpack給html文件中引用的資源例如css、js、img文件加上版本號,避免因爲瀏覽器的緩存形成線上請求的資源依舊是舊版本的東西。

首先新建一個webpack的項目(默認你們已經安裝node的了)javascript

npm init

項目中安裝webpackcss

npm webpack --save-dev
npm webpack-cli --save-dev

而後就能夠開心的寫代碼了html

首先講解單個文件的打包配置

在項目的根目錄下,新建一個webpack.config.js文件,java

npm install --save-dev html-webpack-plugin mini-css-extract-plugin 
clean-webpack-plugin
如今逐一講解各個plugin的做用:
  • html-webpack-plugin

當使用 webpack打包時,建立一個 html 文件,並把 webpack 打包後的靜態文件自動插入到這個 html 文件當中,而且可使用自定義的模版,例如html、pug、ejs,還可配置hash值等一些配置。
具體可配置的參數仍是不少的,像title、meta等等,可參考webpack官網node

  • mini-css-extract-plugin

webpack 4.0之後,把css樣式從js文件中提取到單獨的css文件中;
這在項目中的使用場景是把css文件在js文件中import進來,打包的時候該插件會識別到這個css文件,經過配置的路徑參數生成一個打包後的css文件。jquery

  • clean-webpack-plugin

是用於在下一次打包時清除以前打包的文件,可參考webpack官網webpack

項目中用到的loader
  • babel-loader

Babel把用最新標準編寫的 JavaScript代碼向下編譯成能夠在今天隨處可用的版本git

  • html-loader

它默認處理html中的<img src="image.png">require("./image.png"),同時須要在你的配置中指定image文件的加載器,好比:url-loader或者file-loadergithub

  • url-loader file-loader

用於解決項目中的圖片打包問題,把圖片資源打包進打包文件中,可修改對應的文件名和路徑,url-loader比file-loader多一個可配置的limit屬性,經過此參數,可配置若圖片大小大於此參數,則用文件資源,小於此參數則用base64格式展現圖片;web

  • style-loader css-loader

打包css文件並插入到html文件中;

單頁面打包webpack.config.js的配置
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {
    CleanWebpackPlugin
} = require('clean-webpack-plugin');

const path = require("path");

module.exports = {
    mode: "development",
    entry: path.resolve(__dirname, './src/index.js'),

    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, 'build'),
        // libraryTarget: 'umd'
    },
    module: {
        rules: [{
                test: /\.html$/,
                use: [{
                    loader: "html-loader",
                    options: {
                        attrs: ['img:src', 'link:href']
                    }
                }]
            },
            {
                test: /\.js$/,
                use: {
                    loader: "babel-loader"
                },
                include: path.resolve(__dirname, '/src'),
                exclude: /node_modules/,
            },
            {
                test: /\.(jpg|png|gif|bmp|jpeg)$/,
                use: [{
                    // loader: 'file-loader',
                    loader: 'url-loader',
                    options: {
                        limit: 8192,
                        // name: '[name].[ext]',
                        name: '[name]-[hash:8].[ext]',
                        outputPath: 'images/',

                    }
                }]
            },
            {
                test: /\.pug$/,
                use: {
                    loader: 'pug-loader'
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader']
            },

        ],
    },
    plugins: [
        new CleanWebpackPlugin(),


        new HtmlWebpackPlugin({
            hash: true,
            template: "src/index.html",
            // template: "src/index.pug",
            filename: "bundle.html",
        }),

        new MiniCssExtractPlugin({
            filename: "bundle.css",
            chunkFilename: "index.css"
        }),

    ],
}

多頁面

在plugin中,有多個html-webpack-plugin插件的使用,可生成對應的打包後多個html文件

多頁面打包webpack.config.js的配置
const getPath = require('./getPath')

const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {
    CleanWebpackPlugin
} = require('clean-webpack-plugin');

const path = require("path");


module.exports = {
    mode: "development",
    entry: {
        main: './src/main/main.js',
        side: './src/side/side.js',
        // ...getPath.jsPathList,

    },
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'js/[name].js',
        publicPath: '../',
    },
    module: {
        rules: [{
                test: /\.html$/,
                use: [{
                    loader: "html-loader",
                    options: {
                        attrs: ['img:src', 'link:href']
                    }
                }, ]
            },
            {
                test: /\.js$/,
                use: [{
                    loader: "babel-loader",
                    options: {
                        presets: ['es2015']
                    }
                }],
                include: path.resolve(__dirname, '/src'),
                exclude: /node_modules/,
            },
            {
                test: /\.(jpg|png|gif|bmp|jpeg)$/,
                use: [{
                    // loader: 'file-loader',
                    loader: 'url-loader',
                    options: {
                        limit: 8192,
                        name: '[name]-[hash:8].[ext]',
                        outputPath: './images', //指定放置目標文件的文件系統路徑
                        publicPath: '../images',//指定目標文件的自定義公共路徑
                    }
                }]
            },

            {
                test: /\.pug$/,
                use: {
                    loader: 'pug-loader'
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader']
            },
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        //輸出html文件1
        new HtmlWebpackPlugin({
            hash: true,
            template: "./src/main/main.html", //本地html文件模板的地址
            filename: "html/main.html",
            chunks: ['main'],
        }),

        new HtmlWebpackPlugin({
            hash: true,
            template: "./src/side/side.html",
            filename: "html/side.html",
            chunks: ['side'],
        }),
        // ...getPath.htmlPathList,

        new MiniCssExtractPlugin({
            filename: "css/[name].css",
            chunkFilename: "./src/[name]/[name].css"
        }),

    ]
}

固然也能夠經過函數獲取全部須要打包的文件的路徑,動態在webpack的配置文件中插入

const glob = require("glob");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 *
 * @param {string}  globPath  文件的路徑
 * @returns entries
 */

function getPath(globPath) {
    let files = glob.sync(globPath);

    let entries = {},
        entry, dirname, basename, extname;

    files.forEach(item => {
        entry = item;
        dirname = path.dirname(entry); //當前目錄
        extname = path.extname(entry); //後綴
        basename = path.basename(entry, extname); //文件名
        //文件路徑
        if (extname === '.html') {
            entries[basename] = entry;
        } else if (extname === '.js') {
            entries[basename] = entry;
        }
    });

    return entries;
}

const jsPath = getPath('./src/*/*.js');
const htmlPath = getPath('./src/*/*.html');
const jsPathList = {};
const htmlPathList = [];

console.log("jsPath", jsPath)

Object.keys(jsPath).forEach((item) => {
    jsPathList[item] = path.resolve(__dirname, jsPath[item])
})

Object.keys(htmlPath).forEach((item) => {
    htmlPathList.push(new HtmlWebpackPlugin({
        hash: true,
        template: htmlPath[item],
        filename: `html/${item}.html`,
        chunks: [item],
        // chunks: [item, 'jquery'],
    }))
})

// console.log("htmlPathList", htmlPathList)


module.exports = {
    jsPathList,
    htmlPathList
}

通過打包以後,某個文件夾下的html、css、jpg文件,會被分別打包放進build文件夾下的html文件夾、css文件夾和images文件夾,而且在html文件中引用的其餘資源文件也加上了hash值做爲版本號。

坑:

剛開始的時候url-loader和file-loader都是安裝最新版本的,致使打包後圖片的路徑變成了 <img src="[object Module]"/>
因此此項目用的 "url-loader": "^2.1.0", "file-loader": "^4.2.0"

點擊打開項目github地址

歡迎關注

相關文章
相關標籤/搜索