webpack4入門配置(多頁面)

安裝webpack相關組件

安裝
npm install --save-dev webpack
安裝
npm install --save-dev webpack-cli
安裝
npm install --save-dev webpack-merge
  • webpack-dev-server 用于創(chuàng)建web服務器和使用實時重新加載的能力
安裝
npm install --save-dev webpack-dev-server

配置中會使用到你的插件及加載器

安裝
npm install --save-dev html-webpack-plugin
安裝
npm install copy-webpack-plugin --save-dev
安裝
npm install clean-webpack-plugin --save-dev
  • mini-css-extract-plugin 此插件將CSS提取到單獨的文件中慨灭。它為每個包含CSS的JS文件創(chuàng)建一個CSS文件(webpack4推薦使用css插件)
安裝
npm install --save-dev mini-css-extract-plugin
安裝
npm install uglifyjs-webpack-plugin --save-dev
安裝
npm install --save-dev optimize-css-assets-webpack-plugin

目錄結構

|--src
    |--assets
    |--css
    |--image
    |--js
    |--tool
    |--views
    |--common.js
    |--favicon.ico
    |--index.css
    |--index.html
    |--main.js
|--.babelrc
|--package.json
|--package-lock.json
|--postcss.config.js
|--webpack.base.conf.js
|--webpack.dev.conf.js
|--webpack.prod.conf.js

配置

webpack.base.conf.js

const path = require('path');//引入nodejs路徑模塊, 用于操作文件路徑污朽。
const glob = require('glob');//引入glob, 用于解析路徑(查找文件)
const webpack = require("webpack");//引入webpack, 用于訪問webpack內置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');//通過模板生成html頁面的插件(用于生成html頁面)
const copyWebpackPlugin = require("copy-webpack-plugin");//靜態(tài)資源輸出(原始輸出不編譯)

//檢索目錄拼接入口
function getEntry(){
    var entry = {"main": './src/main.js',"wx":'./src/common.js'};
    //檢索src/views目錄下index.js =》  index.js父目錄名稱作為入口key, index.js所在路徑作為入口路徑
    glob.sync(__dirname+'/src/views/**/@(index).js').forEach(function (name) {
        var start = name.indexOf('/');
        var end =  name.lastIndexOf('/');
        var n = name.slice(start,end);
        var start1 = n.lastIndexOf('/')+1;
        var end1 =  n.length;
        var key = n.slice(start1,end1);
        entry[key] = name;
    });
    return entry;
};

//入口
let entry = getEntry();

//HtmlWebpackPlugin
function getHtml(){
    var plugins=[];
    for(var i in entry ){
        var start = entry[i].indexOf('src')+4;
        var end = entry[i].lastIndexOf('/');
        var pathStr = entry[i].slice(start,end);
        if(i=='wx'){
            plugins.push(
                new HtmlWebpackPlugin({
                    favicon: path.resolve(__dirname, 'src/favicon.ico'),//添加網頁圖標
                    title: "",//添加網頁標題
                    chunks: [i,"code"],
                    filename: path.resolve(__dirname, `dist/insurance-mall/wx.html`),
                })
            );
        }else{
            plugins.push(
                new HtmlWebpackPlugin({
                    favicon: path.resolve(__dirname, 'src/favicon.ico'),//添加網頁圖標
                    title: "",//添加網頁標題
                    'meta': {//添加meta屬性
                        'viewport': 'width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no',
                        'renderer': 'webkit',
                        'X-UA-Compatible': {'http-equiv': 'X-UA-Compatible', 'content': 'IE=Edge'},
                        'MSThemeCompatible': {'http-equiv': 'MSThemeCompatible', 'content': 'Yes'},
                        'imagetoolbar': {'http-equiv': 'imagetoolbar', 'content': 'No'},
                        'format-detection': 'email=no,telephone=no',
                        'MSSmartTagsPreventParsing': 'True',
                        'Access-Control-Allow-Origin': '*',
                        'keywords': '',
                        'description': ''
                    },
                    chunks: [i,'code'],
                    filename:path.resolve(__dirname, `dist/insurance-mall/${pathStr==''?'index':pathStr}.html`),
                    template: path.resolve(__dirname, `src/${pathStr}/index.html`)
                })
            );
        }
    };
    return plugins;
};

//HtmlWebpackPlugin
let plugins = getHtml();

module.exports = {
    //入口文件的配置項
    entry:entry,
    //出口文件的配置項
    output: {
        //所有輸出文件的目標路徑
        path: path.resolve(__dirname, 'dist/insurance-mall')
    },
    //插件牺氨,用于生產模板和各項功能
    plugins: [
        //自動加載模塊
        new webpack.ProvidePlugin({
            $: "jquery", //如:在模塊中使用$('#item'); // <= 起作用會自動加載jquery
            jQuery: "jquery",
            Vue: ['vue/dist/vue.esm.js', 'default']
        }),
        //不編譯輸出
        // new copyWebpackPlugin([{
        //     from: path.resolve(__dirname, "src/assets"),
        //     to: './pulic'
        // }]),
        ...plugins
    ],
    //模塊:例如解讀CSS,圖片如何轉換锁施,壓縮
    module: {
        rules: [
            {
                test: /\.(jsx|js)$/,
                use: {
                    loader: 'babel-loader'  //會自動使用根目錄下的.babelrc配置文件
                },
                include: path.resolve(__dirname, "src"),//檢索src目錄下的.jsx|.js文件并使用babel-loader加載器加載
                exclude: path.resolve(__dirname, "node_modules") //不檢索node_modules目錄下的.jsx|.js文件
            },
            {
                test: /\.(htm|html)$/i,
                use: [{
                        loader: 'html-withimg-loader'
                    }, {
                        loader: 'html-loader',
                        options: {
                            attrs: ['img:data-original', 'img:src']
                        }
                    }]
            },
            {
                test: /\.(png|svg|jpg|gif|jpeg)$/,
                use: [{
                    loader: 'url-loader', //是指定使用的loader和loader的配置參數(shù)
                    options: {
                        limit: 500,  //是把小于500B的文件打成Base64的格式,寫入JS
                        name: "[hash:8].[name].[ext]",
                        outputPath: 'images',  //打包后的圖片放到images文件夾下
                    }
                }, {
                    loader: 'image-webpack-loader'
                }]
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.(csv|tsv)$/,
                use: [
                    'csv-loader'
                ]
            },
            {
                test: /\.xml$/,
                use: [
                    'xml-loader'
                ]
            }
        ]
    },
    //解析模塊請求的選項
    resolve: {
        alias: {
            "@src": path.resolve("src"),
            "@images": path.resolve("src/images")
        }
    },
    optimization: {
        splitChunks: {
            chunks: 'all',
            name:false,
            cacheGroups: {
                commons: {
                    name: 'code',
                    chunks: 'initial',
                    minChunks: 2    //分割前必須共享模塊的最小塊數(shù)咐低。
                }
            }
        },
        removeAvailableModules: true,//當這些模塊已包含在所有父項中時揽思,告訴webpack檢測并從塊中刪除模塊
        removeEmptyChunks: true,//告訴webpack檢測并刪除空的塊
        mergeDuplicateChunks: true,//告訴webpack合并包含相同模塊的塊
    }
    //context: path.resolve(__dirname, 'src')    //指定編譯基本目錄
};

webpack.dev.conf.js

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.base.conf.js');

module.exports = merge(common, {
    //出口文件的配置項
    output: {
        // 「入口分塊(entry chunk)」的文件名模板(出口分塊?)  //打包的文件名稱
        filename:'js/[name].js',
        // 輸出解析文件的目錄见擦,url 相對于 HTML 頁面
        publicPath: "http://localhost:80/insurance-mall/"
    },
    devtool: 'inline-source-map',
    devServer: {
        //設置基本目錄結構,用于找到程序打包地址
        contentBase:path.join(__dirname,'dist'),
        //服務器的IP地址钉汗,可以使用IP也可以使用localhost
        host:'localhost',
        //在所有響應中添加首部內容
        headers: {
            "Access-Control-Allow-Origin": "*"
        },
        open:true,
        //服務端壓縮是否開啟
        //compress:true,
        //繞過主機檢查
        disableHostCheck: true,
        //網絡廣播服務器
        //bonjour: true,
        //此選項允許瀏覽器使用您的本地IP打開
        useLocalIp: false,
        //配置服務端口號
        port:80,
        //是否開啟熱重載
        hot: true
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    module: {
        rules:[
            {
                test: /\.css$/,
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader"
                }, {
                    loader: "postcss-loader"
                }]
            },
            {
                test: /\.less$/,
                use: [{
                    loader: "style-loader"
                },{
                    loader: "css-loader"
                }, {
                    loader: "less-loader"
                }]
            },
            {
                test: /\.scss$/,
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader"
                }, {
                    loader: "sass-loader"
                }]
            }
        ]
    },
    mode: "development"

webpack.prod.conf.js

const merge = require('webpack-merge');//用于合并webpack配置
const CleanWebpackPlugin = require('clean-webpack-plugin');// 清除目錄等(dist)
const MiniCssExtractPlugin = require("mini-css-extract-plugin");//提取css(webpack4支持)
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");//壓縮
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");//縮小輸出css
const common = require('./webpack.base.conf.js');

module.exports = merge(common, {
    //出口文件的配置項
    output: {
        // 「入口分塊(entry chunk)」的文件名模板(出口分塊?)  //打包的文件名稱
        filename:'js/[name].[chunkhash].js',
        publicPath: " "
    },
    plugins: [
        //清理打包代碼目錄
        new CleanWebpackPlugin(['dist']),
        new MiniCssExtractPlugin({
            filename: 'css/[name].[contenthash].css'
        }),
    ],
    module: {
        rules:[
            {
                test: /\.css$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader
                }, {
                    loader: "css-loader"
                }, {
                    loader: "postcss-loader"
                }]
            },
            {
                test: /\.less$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader
                },{
                    loader: "css-loader"
                },{
                    loader: "postcss-loader"
                }, {
                    loader: "less-loader"
                }]
            },
            {
                test: /\.scss$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader
                }, {
                    loader: "css-loader"
                },{
                    loader: "postcss-loader"
                }, {
                    loader: "sass-loader"
                }]
            }
        ]
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    },
    mode:"production"
});

.babelrc

{
  "presets": ["@babel/preset-react", "@babel/preset-env"]
}

postcss.config.js

module.exports={
    plugins: [
        require('autoprefixer') //自動添加前綴插件
    ]
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鲤屡,一起剝皮案震驚了整個濱河市损痰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酒来,老刑警劉巖卢未,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堰汉,居然都是意外死亡辽社,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門衡奥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爹袁,“玉大人远荠,你說我怎么就攤上這事矮固。” “怎么了譬淳?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵档址,是天一觀的道長。 經常有香客問我邻梆,道長守伸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任浦妄,我火速辦了婚禮尼摹,結果婚禮上见芹,老公的妹妹穿的比我還像新娘。我一直安慰自己蠢涝,他們只是感情好玄呛,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著和二,像睡著了一般徘铝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惯吕,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天惕它,我揣著相機與錄音,去河邊找鬼废登。 笑死淹魄,一個胖子當著我的面吹牛,可吹牛的內容都是我干的钳宪。 我是一名探鬼主播揭北,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吏颖!你這毒婦竟也來了搔体?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤半醉,失蹤者是張志新(化名)和其女友劉穎疚俱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缩多,經...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡呆奕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衬吆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梁钾。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逊抡,靈堂內的尸體忽然破棺而出姆泻,到底是詐尸還是另有隱情,我是刑警寧澤冒嫡,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布拇勃,位于F島的核電站,受9級特大地震影響孝凌,放射性物質發(fā)生泄漏方咆。R本人自食惡果不足惜荸实,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一轮洋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦局扶、人聲如沸谬哀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至牙勘,卻和暖如春职恳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背方面。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工放钦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恭金。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓操禀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親横腿。 傳聞我的和親對象是個殘疾皇子颓屑,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355