详解如何使用webpack打包多页jquery项目

作者:脚本小铺时间:2026-10-23 05:31:11浏览:93

本文介绍如何使用webpack和babel打包基于jQuery的多页Web项目。重点讲解如何通过配置多个入口文件实现模块分割加载,解决单文件过大问题。针对多页面场景,详细阐述将CSS单独打包为JS模块以处理图片Base64转换导致体积增大的策略,以及利用HtmlWebpackPlugin和CopyWebpackPlugin生成多HTML页面和静态资源的具体配置方法。

项目背景与打包方案

尽管当前已是2019年,部分项目仍依赖jQuery。为了解决jQuery带来的兼容性问题,并顺利使用ES6语法进行开发,本文探讨利用webpack配合babel进行代码打包发布的方案。

实现该方案需关注以下几个关键点:

多入口与CSS处理策略

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作为全局引用库直接引入。

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目录下的文件结构如下。

项目背景与打包方案

index.js、assist.js和share.js分别是三个页面的入口文件。

index.html、assist.html和share.html是三个页面的模板,HTML代码可以直接编写在此处(当然,如果使用模板文件也是可行的,只要HtmlWebpackPlugin插件支持即可)。

dist文件夹的输出结构如下。

项目背景与打包方案

注意输出文件后缀为.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']
      }]
    },
    
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章