使用webpack打包多頁jquery項目

雖然已經2019年了
不過有一些項目
還是需要用到jquery的
不過考慮到使用jquery的一堆兼容性問題
也爲了可以順利地使用ES6來擼代碼
研究使用webpack+babel打包代碼來發布

幾個重點:
1.爲了將模塊分割加載,不至於一個js文件過大,一個頁面中使用多個js文件
2.由於是多頁項目(多個html),每個頁面使用的js文件都不一致
基於以上兩點,需要配置多個入口文件
3.會把小圖片轉換成base64,所以可能css轉成的js文件會比較大,所以css文件都單獨設置入口js

例如,我們有三個頁面:index、share、assist
三個頁面有通用的css文件:common.css
設置入口文件時,可以這樣設置

entry: {
    // 通用css
    commoncss: path.resolve(__dirname, './src/css/common.css.js'),

    // 主頁
    indexcss: path.resolve(__dirname, './src/css/index.css.js'),
    index: path.resolve(__dirname, './src/index.js'),

    // 頁1
    sharecss: path.resolve(__dirname, './src/css/share.css.js'),
    share: path.resolve(__dirname, './src/share.js'),

    // 頁2
    assistcss: path.resolve(__dirname, './src/css/assist.css.js'),
    assist: path.resolve(__dirname, './src/assist.js'),

}

其中,common.css.js文件中,只有幾行代碼

import '../css/base.css';
import '../css/plugin.css';
import '../css/common.css';

common.css.js文件結束
由於會有一些圖片的base64,所以大小大約100+KB

類似的還有index.css.js和share.css.js和assist.css.js
index.css.js如下

import '../css/index.css';

對,就一句話
打包出來的js文件大小就看引入了多少小圖片了,一般幾百KB

然後,要使用三個webpack的插件

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const jquery = require('jquery');

HtmlWebpackPlugin 用於打包出多個html文件
CopyWebpackPlugin 用於img標籤,後面說
jquery 就是jquery,全局引用

webpack.config.js裏的plugins配置如下

plugins: [
    new webpack.ProvidePlugin({
        $:"jquery"
    }),
    new CopyWebpackPlugin([{
        from: __dirname + '/src/public/'
    }]), // 吧src下public文件夾下的所有內容直接拷貝到dist(輸出目錄)下
    new HtmlWebpackPlugin({
        filename: 'index.htm',
        template: 'src/index.html',
        chunks: ['commoncss', 'indexcss', 'index'],
        inject: 'true',
        hash: true,
    }),
    new HtmlWebpackPlugin({
        filename: 'share.htm',
        template: 'src/share.html',
        chunks: ['commoncss', 'sharecss', 'share'],
        inject: 'true',
        hash: true,
    }),
    new HtmlWebpackPlugin({
        filename: 'assist.htm',
        template: 'src/assist.html',
        chunks: ['commoncss', 'assistcss', 'assist'],
        inject: 'true',
        hash: true,
    })
]

src目錄下的文件如下

clipboard.png

index.js assist.js share.js是三個文件分別的入口文件
index.html assist.html share.html是三個文件的模板,html代碼可以寫在這裏
(當然想用模板文件也是可以的,只要HtmlWebpackPlugin插件支持)

dist文件夾如下

clipboard.png
(爲什麼是htm而不是html,是爲了便於讀者區分模板文件和輸出文件)

我們知道,webpack打包不會打包HtmlWebpackPlugin的template裏的img標籤下的圖片,所以在html裏使用了img標籤的圖片都要放在public文件夾下,CopyWebpackPlugin這個組件會直接把圖片複製過去

關於HtmlWebpackPlugin的具體參數的細則可以上網搜一下,很多這方面的內容
其他的比如loader、babel不在這篇文章想說的重點之列,不贅述

最後,附上webpack.config.js文件


    let actName = 'yourProjectName';// 
    let actKV = {
        name: actName,
        entry: {
            // 通用css
            commoncss: path.resolve(__dirname, './src/css/common.css.js'),

            // 主頁
            indexcss: path.resolve(__dirname, './src/css/index.css.js'),
            index: path.resolve(__dirname, './src/index.js'),

            // 分享頁1
            sharecss: path.resolve(__dirname, './src/css/share.css.js'),
            share: path.resolve(__dirname, './src/share.js'),

            // 分享頁2
            assistcss: path.resolve(__dirname, './src/css/assist.css.js'),
            assist: path.resolve(__dirname, './src/assist.js'),

        }
    };
    

    return {
        entry: actKV.entry,
        target: "web",
        output: {
            path: path.resolve(__dirname + '/dist/'+actName),
            // publicPath: '.\\',
            filename: 'js/[name].js',
            // chunkFilename: "[name].chunk.[hash].js",
        },
        plugins: [
            new webpack.ProvidePlugin({
                $:"jquery"
            }),
            new CopyWebpackPlugin([{
                from: __dirname + '/src/public/'
            }]),
            new HtmlWebpackPlugin({
                filename: 'index.htm',
                template: 'src/index.html',
                chunks: ['commoncss', 'indexcss', 'index'],
                inject: 'true',
                hash: true,
            }),
            new HtmlWebpackPlugin({
                filename: 'share.htm',
                template: 'src/share.html',
                chunks: ['commoncss', 'sharecss', 'share'],
                inject: 'true',
                hash: true,
            }),
            new HtmlWebpackPlugin({
                filename: 'assist.htm',
                template: 'src/assist.html',
                chunks: ['commoncss', 'assistcss', 'assist'],
                inject: 'true',
                hash: true,
            })
        ],
        mode: 'development',
        node: {
            __filename: true,
            __dirname: true
        },
        devtool: isProduction ? 'source-map':'inline-source-map',
        devServer:{
            inline: true,
            open: true, 
            historyApiFallback: true, 
            // host: ip.address(),
            host: 'localhost',
            progress: true,
            contentBase: "./dist/",
            port: 3430,
            historyApiFallback:true,
            publicPath:'/src/',
            proxy: {
                '*': {
                    target: 'http://127.0.0.1:3430',
                    secure: false
                }
            },
        },
        resolve: {
            alias: {
            },
            extensions: ['.js', '.less', '.css', '.vue', '.jsx'],
        },
        externals: {
        },
        module: {
            rules: [{
                test: /\.vue$/,
                loader: 'vue-loader',
            }, {
                test: /\.js$/,
                include: path.join(__dirname,'/src'),
                exclude: path.resolve(__dirname, 'node_modules'),
                use:[
                    {
                        loader: 'babel-loader',
                        query: {
                            presets: ['es2015']
                        }
                    }
                ]
            }, {
                test: /\.xml$/,
                loader: "xml-loader"
            }, {
                test: /\.(css|less)$/,
                loader: "style-loader!css-loader",
            }, 
            {
                test: /\.(png|jpg|jpeg|gif|icon|webp)$/,
                loader: 'url-loader',
                options: {
                    limit: 16384,
                    name: 'images/[name].[hash:5].[ext]',
                }
            },
            {
                test: /\.(woff|woff2|svg|eot|ttf)\??.*$/,
                loader: "file-loader?&name=assets/fonts/[name].[ext]"
            }, {
                test: /\.txt$/,
                loader: "text-loader"
            },{
                test: /\.jsx$/,
                exclude: /node_modules/,
                loaders: ['jsx-loader', 'babel-loader']
            }]
        },
        
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章