初学webpack(3.X版本),手动搭建的一个简单多页面项目

版权声明:原创内容转载请注明出处: https://blog.csdn.net/wuzhe128520/article/details/89789190

这个配置是基于webpack3.X版本的;
1、第一个文件webpack.util.js,主要作用是自动读取入口文件并进行配置,自动生成html模板的配置文件

const glob = require('glob'),
      path = require('path'),
      htmlWebpackPlugin = require('html-webpack-plugin'),
      //公共使用的第三方库,单独打包到一个文件里避免长效缓存失败
      vendors = ['jquery', 'lodash'];

const webpackUtil = {

   //文件路径
      fileDir: {

          //打包前的原始路径
          origin: {
            //入口文件的路径(正则表示)
            entryJs: './src/js/pages/',

            //页面模板路径(正则表示)
            tmpls: './src/view/pages/'
          } ,

          //打包后的路径
          build: {

              //打包后的html存放目录
              view: './view/',

          }
      },

  //根据给定的值删除数组对应的值
  deleteByValue: function(ary, value, isDeleteAll){

          var i = 0,
              length = ary.length;

          for(; i < length; i++){

              if(value === ary[i]){
                  ary.splice(i,1);
                  //是否删除所有跟value一样的值,默认只删除最近的一个
                  if(!isDeleteAll){
                      break;
                  }
              }
          }
          return ary;
    },

    //获取所有的入口地址
  getEntry: function(globPath) {

      //找到正则globPath匹配的文件名(包括完整的路径)
      let files = glob.sync(globPath),
          entries = {},
          entry,
          dirname,
          basename,
          pathname,
          extname;

      entries['vendors'] = vendors;
      for (let i = 0; i < files.length; i++) {
           entry = files[i];

           //文件的路径
           dirname = path.dirname(entry);

           //文件名的后缀
           extname = path.extname(entry);

           //方法返回一个 path 的最后一部分
           basename = path.basename(entry, extname);
           pathname = path.join(dirname, basename);

           entries[basename] = entry;
      }

      return entries;
  },

  /**
   * [配置webpack插件的选项]
   * @param  {[string]} tmplsDir [html模板路径]
   * @param  {[string]} ext      [模板的后缀名]
   * injectArray: 需要将js插入到head的页面数组
   * @return {[type]}          [description]
   */
  configHtmlWebpackOptions: function(tmplsDir, ext, injectArray, entries, config) {

      let pages = Object.keys(entries);

      pages = webpackUtil.deleteByValue(pages,'vendors');

      //去除vendors这个chunk,已在其他插件处理
      pages.forEach(function(pagename) {

         let htmlWebpackOption = {

            filename: webpackUtil.fileDir.build.view + pagename + '.html',
            template: webpackUtil.fileDir.origin.tmpls + pagename + '.' +ext,
            inject: injectArray && (injectArray.indexOf(pagename) !== -1)&&'head'||'body',
            minify: {
                removeComments: true,
                collapseWhitespace: false
              }
          };

          if(pagename in config.entry) {
              htmlWebpackOption.favicon = './src/images/favicon.ico',
              htmlWebpackOption.chunks = ['vendors', 'runtime', pagename]
          }

          config.plugins.push(
              new htmlWebpackPlugin(htmlWebpackOption)
          );
      });
    }
};
module.exports = webpackUtil; 

2、webpack.comm.js 公用配置;主要设置插件和各种loader

const path = require('path'),
      webpackUtil = require('./webpack.util.js'),
      cleanWebpackPlugin = require('clean-webpack-plugin'),
      extractTextWebpackPlugin = require('extract-text-webpack-plugin'),
      copyWebpackPlugin = require('copy-webpack-plugin'),
      webpack = require('webpack'),

      //文件路径配置
      fileDir = webpackUtil.fileDir;

let config = {
        resolve: {
            extensions: [".js", ".less", ".css"] // 后缀名自动补全
        },
        plugins: [

            new cleanWebpackPlugin(['dist']),

             //提取行内css样式到单独的文件
            new extractTextWebpackPlugin('css/[name].css'),

            new copyWebpackPlugin([{
                from: __dirname + '/src/js/lib/old-plugins/',
                to: __dirname + '/dist/js/',
            }]),

            //全局加载jq(只能在webpack模板中使用)
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery',
                'window.jQuery': 'jquery',
                'window.$': 'jquery',
            }),

        ],

        module: {

                rules: [
                        {
                           test: require.resolve('jquery'),
                           use: [
                           {
                                loader: 'expose-loader',
                                options: '$'
                           },
                           {
                              loader: 'expose-loader',
                              options: 'jQuery'
                           }
                           ]
                        },
                        {
                          test: /\.js$/,
                          include: path.resolve(__dirname, 'src/js'),
                          exclude: path.resolve(__dirname, 'src/js/lib'),
                          use: ['babel-loader']
                        },
                        //抽离css样式
                        {
                            test: /\.css$/,
                            use: extractTextWebpackPlugin.extract({
                                fallback: 'style-loader',
                                use: [
                                  {
                                    loader: 'css-loader',
                                    options: {
                                      minimize: true

                                    }
                                  },
                                  {
                                    loader: 'postcss-loader'
                                  }
                                ]
                            })
                        },
                        /*
                        * 将图片混合到css中
                        * url-loader:与file-loader类似;如果文件小于限制的字节大小,它可以返回一个dataURL(base64格式的图片描述字符串,减少http请求)
                        *
                         *  */
                        {
                            test: /\.(png|jpg|gif|ico)$/,
                            use: [
                                {
                                    loader: 'url-loader',
                                    options: {
                                        name: 'images/[name].[ext]',

                                        //将8KB以下的图片转换为base64的dataURL输出形式
                                        limit: 8192

                                    }

                                }
                            ],
                        },

                        //html页面路径自动转换不正确
                        {
                            test: /\.html$/,
                            use: [
                                'html-loader'
                            ]
                        },
                        {
                            test: /\.ejs$/,
                            use: [
                                'ejs-loader'
                            ]
                        },

                        //加载字体
                        {
                            test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
                            use: [
                                {
                                    loader: 'file-loader',
                                    options: {
                                        name: 'fonts/[name].[ext]'
                                    }
                                }
                            ]
                        },

                        //编译less
                        {
                            test: /\.less$/,
                            loader: extractTextWebpackPlugin.extract({
                                fallback: 'style-loader',
                                use: [
                                    {
                                      loader: 'css-loader',
                                      options: {
                                        minimize: true
                                      }
                                    },
                                    {
                                      loader: 'postcss-loader'
                                    },
                                    {
                                      loader: 'less-loader'
                                    }
                                ]
                            })
                        }
                ]
            }
};

var entries = webpackUtil.getEntry(fileDir.origin.entryJs + '**/*.js');
config['entry'] = entries;
webpackUtil.configHtmlWebpackOptions(fileDir.origin.tmpls + '**/*.html', 'html', [],entries, config);
module.exports = config;

3、webpack开发模式下;设置开发模式下得服务器相关配置,以及打包后的文件输出配置

const merge = require('webpack-merge'),
      path = require('path'),
      webpack = require('webpack'),
      common = require('./webpack.comm.js');

module.exports = merge(common, {

    devtool: 'inline-source-map',

    devServer: {
        /*
        告诉服务器从哪里提供内容.只有在你想要提供静态文件时才需要。
        推荐使用绝对路径。
        */
        // contentBase: path.resolve(__dirname, 'dist'),

        //此路径下的打包文件可在浏览器中访问;确定从哪里提供bundle,并且此选项优先;(是一个虚拟目录,实际上引用的是内存中的文件)
        //publicPath: '/build/' //总是以斜杠开始和结尾
        // 可以局域网访问
        // host: '0.0.0.0',
        contentBase: path.resolve(__dirname, 'dist'),
        publicPath: "/dist/",
        hot: true, //开启热点
        inline: true, //开启页面自动刷新
        compress: true,
        port: '8088', //设置端口号
        //监控在contentBase选项里的文件,一旦文件发生改变将会触发整个页面重新加载;
        watchContentBase: false,
        proxy: {
            // 反向代理 /cfy 开头的都转发到后台
            '/cfy': {
                target: 'http://192.168.1.77:8080',
                secure: false,
                changeOrigin:true
            },
            '/hrManeger': {
                target: 'http://192.168.1.55:8080',
                secure: false,
                changeOrigin:true
            },
            '/user': {
                target: 'http://192.168.1.55:8080',
                secure: false,
                changeOrigin:true
            },
            '/user': {
                target: 'http://192.168.1.77:3000',
                secure: false,
                changeOrigin:true
            },
        }
    },

    plugins: [

        //当热更新启用的时候,插件会影响模块显示的相对路径;建议在开发模式下使用;
        new webpack.NamedModulesPlugin(),

        //热加载
        new webpack.HotModuleReplacementPlugin()
    ],
    output: {

            //设置生成打包后的根目录
            path: path.resolve(__dirname, 'dist'),

            //生成后的bundle.js的访问目录
            publicPath: '/dist/',l

            filename: 'js/[name].bundle.js', //这里的路径是相对于build的

            //未配置在entry中,但是在入口js文件中被引用的所有js文件被打包后的路径和文件名
            chunkFilename: 'js/[id].bundle.js'

        }
});

4、webpack.prod.js生产环境下的配置;

const merge = require('webpack-merge'),
      path = require('path'),
      webpack = require('webpack'),
      uglifyJsPlugin = require('uglifyjs-webpack-plugin'),
      common = require('./webpack.comm.js');

module.exports = merge(common, {

    devtool: 'source-map',

    plugins: [

        //压缩js代码
        new uglifyJsPlugin(),

        //将很少修改的第三方库单独存合并在一个js文件里
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendors'
        }),

        //合并公共的文件(包含js和css)
        new webpack.optimize.CommonsChunkPlugin({

            name: 'runtime'

        }),

        //添加新的依赖后,保证hash不会乱修改使长缓存失效
        new webpack.HashedModuleIdsPlugin(),
    ],
    output: {

            //设置生成打包后的根目录
            path: path.resolve(__dirname, 'dist'),

            //生成后的bundle.js的访问目录
            publicPath: '/hrManeger/dist/',

            filename: 'js/[name].bundle.js', //这里的路径是相对于build的

            //未配置在entry中,但是在入口js文件中被引用的所有js文件被打包后的路径和文件名
            chunkFilename: 'js/[id].bundle.js'

    }
});

猜你喜欢

转载自blog.csdn.net/wuzhe128520/article/details/89789190