webpack开发配置(webpack.base.js/webpack.dev.js/webpack.prod.js)

源代码 https://github.com/kingov/webpack-learning

项目初始结构分析

通常项目会分成三个运行环境:开发人员在本地跑的开发环境(dev)、测试人员用来做黑盒测试的测试环境(test)和线上运行的生产环境(production)。
简单起见,本文只考虑开发环境(dev)和生产环境(prod),测试环境可以自行类比。
综上,webpack的配置需要有两套,同时两套配置必然会存在相同的部分,故新建目录与文件如下图:
这里写图片描述
同时引入一个库webpack-merge用于合并base config和特定环境的config

cnpm i -D webpack-merge

开始写webpack config

webpack-config/base.js

module.exports = {
  //common config
};

webpack-config/dev.js, webpack-config/prod.js

const webpackMerge = require('webpack-merge');
const base = require('./base');
module.exports = webpackMerge(base, {
  //specific config
});

webpack.config.js

const devModule = require('./webpack-config/dev');
const prodModule = require('./webpack-config/prod');
let finalModule = {};
let ENV = process.env.NODE_ENV;     //此处变量可由命令行传入
switch (ENV) {
  case 'dev':
    finalModule = devModule;
    break;
  case 'prod':
    finalModule = prodModule;
    break;
  default:
    break;
}
module.exports = finalModule;

编写npm scripts,区分环境

package.json

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "scripts": {
    "dev": "cross-env NODE_ENV=dev webpack",
    "prod": "cross-env NODE_env=prod webpack"
  },
  "devDependencies": {
    "webpack": "^2.2.0",
    "webpack-merge": "^2.6.1"
  }
}

由于*unix和windows设置NODE_ENV的语句有所差异,此处用到了一个库cross-env以达到兼容的目的

cnpm i -D cross-env

从dev环境写起

新建一个src目录用户存放项目源文件,同时在src下新建一个index.js作为打包的入口
webpack-dev-server
安装webpack-dev-server

    cnpm i -D webpack-dev-server

配置webpack config
webpack-config/dev.js

    ...
    module.exports = webpackMerge(base, {
      entry: process.cwd() + '/src/index.js',
      output: {
        filename: '[name].bundle.js'
      },
      devtool: 'eval-source-map'   //enable srouce map
    });

修改npm scripts
package.json

    {
     ...
     "scripts": {
       "dev": "cross-env NODE_ENV=dev webpack-dev-server --inline --hot --host 0.0.0.0",
       ...
     }
    }

htmlWebpackPlugins

src目录下新建一个index.html作为template,htmlWebpackPlugins会根据这个template生成网站的index.html,同时自动写入bundle依赖。
src下放一个favicon.ico作为网站的icon
安装htmlWebpackPlugins

    cnpm i -D html-webpack-plugin

配置webpack config
webpack-config/dev.js

    ...
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    ...
    module.exports = webpackMerge(base, {
      ...
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: process.cwd() + '/src/index.html',
          favicon: process.cwd() + '/src/index.html'
        })
      ]
      ...
    });

到这一步算是完成了最基本的开发环境配置,命令行执行npm run dev,然后浏览器打开localhost:8080就能看到成果
将npm scripts中的start命令指向npm run dev,这样每次开始开发只需要执行npm start
package.json

{
  ...
  "scripts": {
    ...
    "start": "npm run dev"
    ...
  }
  ...
}

Loaders(Rules)

webpack本身只能处理js模块,如果需要处理其他类型的文件,就需要Loaders进行转换
ES6+支持
ES6+虽然不能直接被浏览器全部识别,但是能用babel转换成ES5代码。
安装babel编译相关依赖

    cnpm i -D babel-core babel-preset-latest babel-preset-stage-2 babel-runtime babel-plugin-transform-runtime babel-loader

新建.babelrc文件并写入:
.babelrc

    {
      "presets": ["latest", "stage-2"],
      "plugins": ["transform-runtime"]
    }

配置rules
webpack-config/dev.js

    module.exports = webpackMerge(base, {
      ...
      module: {
        rules: [
          ...
          {
            test: /\.js$/,
            exclude: [/node_modules/],
            loader: 'babel-loader'
          }
          ...
        ]
      }
      ...
    });

css处理

现如今css预处理器已经成为前端开发的标配,Sass(Scss),Less和Stylus各行其道,个人偏好scss。
PostCss可以作为一个后处理器,实现为css自动添加浏览器前缀等功能

  • 安装相关依赖
    cnpm i -D style-loader css-loader postcss-loader autoprefixer node-sass sass-loader
  • 新建postcss.config.js
    postcss.config.js
    module.exports = {
      plugins: [
        require('autoprefixer')({browsers: ['last 2 versions', 'iOS 7', 'Firefox > 20']})
      ]
    };
  • 配置rules
    webpack-config/dev.js
    module.exports = webpackMerge(base, {
      ...
      module: {
        rules: [
          ...
          {
            test: /\.scss$/,
            exclude: [/node_modules/],
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              'postcss-loader',
              {
                loader: 'sass-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          }
          ...
        ]
      }
      ...
    });

html模板、图片等的处理

  • 安装相关依赖
    cnpm i -D html-loader file-loader url-loader
  • 配置rules
    webpack-config/dev.js
    module.exports = webpackMerge(base, {
      ...
      module: {
        rules: [
          ...
          {
            test: /\.html$/,
            loader: 'html-loader',
            options: {
              minimize: true
            }
          },
          {
            test: /\.(jpe?g|png|gif|svg)$/i,
            loader: 'url-loader',
            options: {
              limit: 10000,
              hash: 'sha512',
              publicPath: '/',
              name: 'assets/images/[hash].[ext]'
            }
          }
          ...
        ]
      }
      ...
    });

至此,dev环境配置完成

配置production环境

抽出公共部分

  • entry可以共用,prod的output需要加上文件chunkhash用来刷新缓存,并将文件输出至dist目录
    webpack-config/dev.js
    - entry: process.cwd() + '/src/index.js',

webpack-config/base.js

    module.exports = {
      entry: process.cwd() + '/src/index.js',
    };

webpack-config/prod.js

    const webpackMerge = require('webpack-merge');
    const base = require('./base');
    module.exports = webpackMerge(base, {
      output: {
        filename: 'bundle.[chunkhash].js',
        path: process.cwd() + '/dist'
      },
    });
  • HtmlWebpackPlugin公共
    webpack-config/dev.js
    -new HtmlWebpackPlugin({
    -  filename: 'index.html',
    -  template: process.cwd() + '/src/index.html',
    -  favicon: process.cwd() + '/src/index.html'
    -})

webpack-config/base.js

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
      ...
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: process.cwd() + '/src/index.html',
          favicon: process.cwd() + '/src/index.html'
        })
      ],
    };
  • js、html和图片loader公共,prod的css loader需要使用ExtractTextPlugin将css从js中分离出来
    webpack-config/dev.js
    -{
    -  test: /\.js$/,
    -  exclude: [/node_modules/],
    -  loader: 'babel-loader'
    -}
    ...
    -{
    -  test: /\.html$/,
    -  loader: 'html-loader',
    -  options: {
    -    minimize: true
    -  }
    -},
    -{
    -  test: /\.(jpe?g|png|gif|svg)$/i,
    -  loader: 'url-loader',
    -  options: {
    -    limit: 10000,
    -    hash: 'sha512',
    -    publicPath: '/',
    -    name: 'assets/images/[hash].[ext]'
    -  }
    -}

webpack-config/base.js

    ...
    module.exports = {
      ...
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: [/node_modules/],
            loader: 'babel-loader'
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
            options: {
              minimize: true
            }
          },
          {
            test: /\.(jpe?g|png|gif|svg)$/i,
            loader: 'url-loader',
            options: {
              limit: 10000,
              hash: 'sha512',
              publicPath: '/',
              name: 'assets/images/[hash].[ext]'
            }
          }
        ]
      }
    };
cnpm i -D extract-text-webpack-plugin@beta

webpack-config/prod.js

    ...
    const ExtractTextPlugin = require("extract-text-webpack-plugin");
    ...
    module: {
      rules: [
        {
          test: /\.scss$/,
          exclude: [/node_modules/],
          use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [
              {
                loader: 'css-loader',
                options: {
                  minimize: true
                }
              },
              'postcss-loader',
              'sass-loader'
            ]
          })
        }
      ]
    },
    ...
    plugins: [
      new ExtractTextPlugin({
        filename: "bundle.[chunkhash].css"
      })
    ],

production环境的其它处理

  • 使用UglifyJsPlugin压缩js
cnpm i - D uglifyjs-webpack-plugin

webpack-config/prod.js

...
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
...
module.exports = webpackMerge(base, {
  ...
  const webpack = require('webpack');
  ...
  plugins: [
    ...
    new UglifyJSPlugin({
      compress: {
        warnings: false,
      },
      output: {
        comments: false
      }
    })
    ...
  ]
  ...
})
...

使用CleanWebpackPlugin清空output目录

构建前先清空,防止出现垃圾文件

cnpm i -D clean-webpack-plugin

webpack-config/prod.js

...
module.exports = webpackMerge(base, {
  ...
  plugins: [
    ...
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    ...
    new CleanWebpackPlugin(['dist'], {
      root: process.cwd(),
      exclude: []
    })
    ...
  ]
  ...
})
...

至此,production环境配置完毕,同时抽出了公共部分

配置resolve.alias

开发的时候如果有一个很深的目录比如:src/a/b/c/d/, 然后在d目录下的一个模块需要引入a目录下的模块,需要这样写:import ‘../../../some-module’,为了方便可以配置一个为src目录配置一个alias,这样模块引入只需要这样写:import src/a/some-module。
webpack-config/base.js

    ...
    const path = require('path');
    ...
    module.exports = {
      ...
      resolve: {
        extensions: ['.js'],
        alias: {
          src: path.resolve(__dirname, './../src')
        }
      }
      ...
    };
  • 通常dev环境和production环境的配置参数比如api domain会有差异,所以需要利用alias将用户两个环境配置文件区分开来
    src目录下新建config目录,src/config目录下新增三个文件:base.js、dev.js、prod.js
    webpack-config/base.js
    export default {
      version: '1.0.0'
    }

webpack-config/dev.js

    import base from './base'
    export default {
      ...base,
      env: 'dev'
    }

webpack-config/prod.js

    import base from './base'
    export default {
      ...base,
      env: 'prod'
    }
  • 配置alias
    webpack-config/dev.js
    ...
    const path = require('path');
    ...
    module.exports = webpackMerge(base, {
      ...
      resolve: {
        alias: {
          config: path.resolve(__dirname, './../src/config/dev.js')
        }
      }
      ...
    })
    ...

webpack-config/prod.js

    ...
    const path = require('path');
    ...
    module.exports = webpackMerge(base, {
      ...
      resolve: {
        alias: {
          config: path.resolve(__dirname, './../src/config/prod.js')
        }
      }
      ...
    })
    ...
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在一个Vue项目中,常见的Webpack配置文件包括: 1. `webpack.base.config.js`:这是一个基础的Webpack配置文件,定义了通用的配置选项,例如入口文件、输出路径、模块解析规则等。它是不同环境配置文件的基础。 2. `webpack.dev.conf.js`:这是用于开发环境的Webpack配置文件。它会基于`webpack.base.config.js`进行扩展和覆盖,添加一些开发环境特定的配置选项,例如热重载、Source Maps等。 3. `webpack.prod.conf.js`:这是用于生产环境的Webpack配置文件。它同样会基于`webpack.base.config.js`进行扩展和覆盖,添加一些生产环境特定的配置选项,例如代码压缩、资源优化等。 4. `webpack.config.js`:在某些项目中,可能会使用单一的Webpack配置文件来同时处理开发环境和生产环境。这个文件会根据环境变量动态地配置Webpack。它可能会引入`webpack.base.config.js`并根据环境变量来扩展或覆盖一些配置选项。 5. `config/index.js`:这是一个存放项目全局配置的文件夹。其中的`index.js`文件包含了一些开发和生产环境的全局配置选项,例如服务器地址、端口号、是否开启热重载等。你可以在这个文件中进行自定义配置以满足项目的需求。 需要注意的是,具体的配置内容和结构可能因项目而异,你可以根据项目需求自定义修改这些配置文件。这些文件的目的是为了方便开发者根据不同环境和需求来配置和优化Webpack打包过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值