likes
comments
collection
share

Webpack的一些细节

作者站长头像
站长
· 阅读数 15

Webpack几个核心概念

  1. 入口(Entry): webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。

  2. 输出(Output): webpack 打包后的资源(bundles)输出到哪里去,以及如何命名。

  3. Loader(加载器): 让 webpack 能够去处理那些非 JavaScript 文件,webpack 自身只理解 JavaScript

  4. 插件(Plugins): 可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。

  5. 模式(Mode): webpack 使用相应模式的配置。development开发模式,特点:速度快,打包的文件夹大;production 上线模式,速度慢,文件小

Webpack的构建流程

Webpack启动后,从entry入口文件开始,解析entry依赖的所有module,找到每一个module的时候,会根据module.rules里面的不同loader加载器进行转换(因为Webpack自身只理解JavaScript),转换后再解析出当前module依赖的其他一些模块,这些module在entry里面,会进行分组,解析成一个个的代码块,最后Webpack将所有的代码块转换成output输出的文件。

Webpack的一些细节

webpack.config.js规范

commonjs模块化规范通过module.exports={}来暴露

const path = require('path')

// html插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const htmlPlugin = new HtmlWebpackPlugin({
  template:"./src/index.html",  //本地模板文件
  filename:"./index.html"  //生成文件所在目录&文件名
})

// clean-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

// mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const minicssextractplugin = new MiniCssExtractPlugin({
  filename:'css/[name].css'
})

//压缩css
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

module.exports = {
  mode:"development",
  // 指定入口文件
  entry:"./src/index.js",
  // 生成文件存放的路径
  output:{
    path:path.join(__dirname,'dist'),
    filename:"js/bundle.js",
    assetModuleFilename: 'images/[hash][ext][query]'
  },
  // 对webpack-dev-server进行更多的配置
  devServer:{
    open:true,
    host:'127.0.0.1',
    port:3000
  },
  // 插件
  plugins:[
    htmlPlugin,
    new CleanWebpackPlugin(),
    minicssextractplugin
  ],
  module:{
    rules:[
      // {test:/\.css$/i,use:['style-loader','css-loader']},
      {
        test:/\.css$/i,
        use:[MiniCssExtractPlugin.loader,'css-loader']
      },
      {test: /\.(png|jpg|gif|svg)$/i,type: 'asset/resource'},
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[hash][ext][query]'
        }
      },
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  optimization:{
    minimizer:[new CssMinimizerPlugin()],
    minimize:true
  }
}

打包指令:webpack

loader是从下往上执行的。css-loader以commonjs模块来整合到相应的js中,里面的内容是样式字符串。当在页面中打开时,它会创建 sytle 标签,将 js 中的样式资源插入进行,添加到 head 中生效。

require和import的区别

  1. import在代码编译时被加载,所以必须放在文件开头,require在代码运行时被加载,所以require理论上可以运用在代码的任何地方,所以import性能更好。
  2. import引入的对象被修改时,源对象也会被修改,相当于浅拷贝,require引入的对象被修改时,源对象不会被修改,官网称值拷贝,我们可以理解为深拷贝。
  3. import有利于tree-shaking(移除JavaScript上下文中未引用的代码),require对tree-shaking不友好。
  4. import会触发代码分割(把代码分离到不同的bundle中,然后可以按需加载或者并行加载这些文件),require不会触发。
  5. import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法,require 是 AMD规范引入方式。

webpack将所有的import moduleName from 'xxModule’都变成了一个Map对象,key为文件路径,value为一个可执行的函数,而函数内容其实就是模块中导出的内容,在webpack打包中,import和require都会变为_webpack_require_。

Webpack的一些细节