webpack4.x 总结

1,292 阅读3分钟

最早接触webpack时3.x,随着前端技术的发展,早已经不是之前,建一个html文件,里面引入js,css打开网页就可以看到效果静态页开发年代,现在的前段框架,vue也好,react 也罢,都需要依赖于工具的支持,才能转换成浏览器可识别的语言,除此之外,webpack还做了例如代码压缩混淆,公共代码提取,autoprefixer,热更新等等一系列优化的功能,可见在现在这个发展趋势下,掌握webpack的配置,对前端来说是非常重要的,今天就来聊一聊webpack4.x。

安装:

1.npm install webpack webpack-cli -g

webpack-cli 是使用 webpack 的命令行工具,在 4.x 版本之后不再作为 webpack 的依赖了,我们使用时需要单独安装这个工具。

2.npm install webpack -D

作为项目中的依赖使用。

实验:

在package.json scripts 中加入build 命令:

 "scripts": {
    "build": "webpack --mode production"
  }

新建src/index.js, 随便写点js进去后在控制台执行npm run build

目录中会出先一个 dist 文件夹,打开里面的main.js文件, 已经被混淆压缩过。

核心概念:

  1. entry 入口文件。
module.exports = {
    entry: './src/index.js' 
}

// 上述配置等同于
module.exports = {
      entry: {
        main: './src/index.js'
      }
}

// 或者配置多个入口
module.exports = {
      entry: {
        foo: './src/page-foo.js',
        bar: './src/page-bar.js', 
        // ...
      }
}

  1. loader 文件转换器,例如把es6转换为es5,scss转换为css。
module: {
  // ...
  rules: [
    {
      test: /\.jsx?/, // 匹配文件路径的正则表达式,通常我们都是匹配文件类型后缀
      include: [
        path.resolve(__dirname, 'src') // 指定哪些路径下的文件需要经过 loader 处理
      ],
      use: 'babel-loader', // 指定使用的 loader
    },
  ],
}...
  1. plugin 插件,就可以理解为代码转换的工作都交给loader,打包构建的工作都交给plugin。
const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  plugins: [
    new UglifyPlugin()
  ],
}
  1. output,输出文件:
module.exports = {
  // ...
  output: {
    //输出目录
    path: path.resolve(__dirname, 'dist'),
    //输出文件名
    filename: 'bundle.js',
    
  },
}

// 或者多个入口生成不同文件
module.exports = {
  entry: {
    foo: './src/foo.js',
    bar: './src/bar.js',
  },
  output: {
    filename: '[name].js',
    //输出的文件名都按上面对应的key值来(foo, bar)
    path: __dirname + '/dist',
  },
}

// 路径中使用 hash,每次构建时会有一个不同 hash 值,避免发布新版本时线上使用浏览器缓存
module.exports = {
  // ...
  output: {
    filename: '[name].js',
    //如果文件没有改动,hash是不会变化的
    path: __dirname + '/dist/[hash]',
  },
}...

webpack 配置:

webpack 4.x 的一个核心买点就是 0 配置,所有配置都可以通过package.json类似如下的写法实现:

"scripts": {
  "scripts": {
  "dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js",
  "build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}
}

但这种网上吐槽的声音比较多,而且很多实际需要的功能要么不支持,要么不知如何写,还是先建立wepack.config.js,踏实一步步来吧!

把上面的几部分合在一起,就是一个简单的webpack配置:

const path = require('path')
//压缩混淆代码
const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  entry: './src/index.js',

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },

  module: {
    rules: [
      {
        test: /\.jsx?/,
        include: [
          path.resolve(__dirname, 'src')
        ],
        use: 'babel-loader',
      },
    ],
  },

  // 代码模块路径解析的配置
  resolve: {
   //resolve.modules配置webpack去哪些目录下寻找第三方模块
    modules: [
      "node_modules",
      path.resolve(__dirname, 'src')
    ],
    
    /**
    *在导入语句没带文件后缀时,
    *webpack会自动带上后缀去尝试访问文件是否存在。
    *resolve.extensions用于配置在尝试过程中用到的后缀列表,
    *依次往后找。
    */
    //
    extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
  },

  plugins: [
    new UglifyPlugin()
  ],
}...

有了 webpack.config.js 控制台输入webpack 即可运行。

上述只是一个简单的 webpack.config.js 配置,但好像完全没有什么用 😂!

下面就来配置一个可以满足前端大概需求的webpack.config.js :

前端打包一般需要达到的目的:

  • 构建我们发布需要的 HTML、CSS、JS 文件
  • 使用 CSS (sass,less)
  • 处理和压缩图片
  • 使用 Babel ES6 -》 ES5
  • 本地起服务
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  entry: './src/index.js',

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },

  module: {
    rules: [
      {
        test: /\.jsx?/,
        include: [
          path.resolve(__dirname, 'src'),
        ],
        use: 'babel-loader',
      },
      {
        test: /\.less$/,
        // 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
        use: ExtractTextPlugin.extract({ 
          fallback: 'style-loader',
          use: [
            'css-loader', 
            'less-loader',
          ],
        }), 
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader'
          },
        ],
      },
    ],
  },

  // 代码模块路径解析的配置
  resolve: {
    modules: [
      "node_modules",
      path.resolve(__dirname, 'src'),
    ],

    extensions: [ ".js", ".json", ".jsx"],
  },

  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // 配置输出文件名和路径
      template: 'src/index.html', // 配置文件模板
    }),
    new ExtractTextPlugin('[name].css'),
  ],
}

未完待续。。。

参考文件:

webpack的Resolve配置