飞道的博客

webpack基础入门

246人阅读  评论(0)

一、核心概念

  • Entry:入口,Webpack执行构建的第一步是从Entry开始,可抽象为输入;
  • Module:模块,在Webpack里一切皆模块,一个模块对应一个文件。Webpack会从配置的Entry开始递归找出所有依赖的模块;
  • Chunk:代码块,一个Chunk由多个模块组合而成,用于代码合并与分割;
  • Loader:模块转换器,用于将模块的原内容按照需求转换为新内容;
  • Plugin:扩展插件,在Webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果或者做我们想做的事;
  • Output:输出结果,在Webpack经过一系列处理并得出最终想要的代码后输出的结果。

大致流程如下:
Webpack在启动后会从Entry里配置的Module开始,递归解析Entry依赖的所有Module。每找到一个Module,就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析当前Module依赖的Module。这些模块会根据Entry为单位进行分组,一个Entry及其所有依赖的Module被分到一个组内,也就是一个Chunk。最后,Webpack会将所有Chunk转换成文件输出。在整个流程中,Webpack会在恰当的时机执行Plugin里定义的逻辑。

详解Webpack核心概念

(一)、Entry

Entry配置是必填的,如果不填将会导致Webpack报错,退出。
1、context:Webpack在寻找相对路径的文件时会以context为根目录,context默认为执行启动Webpack时所在的当前工作目录。

context: path.resolve(__dirname, '../'),

需要注意的是,context必须是一个绝对路径的字符串。
2、Entry类型:可以为string、array、object三者中任意类型。

  • string:'./app/entry'、入口模块的文件路径,可以是相对路径;
  • array:['./app/entry1','./app/entry2']、入口模块的文件路径,可以是相对路径;
  • object:{a:'./app/entry',b:['./app/entry1','./app/entry2']},配置多个路口,每个入口生成一个chunk。

3、Chunk的名称
Webpack会为每个生成的Chunk取一个名称,Chunk的名称和Entry的配置有关。

  • 如果Entry是一个string或array,就只会生成一个Chunk,这时Chunk的名称是main;
  • 如果Entry是一个object,那么会出现多个Chunk,这时Chunk的名称是object键值对中键的名称。

4、为MPA应用配置Entry

在untils.js文件中添加如下代码逻辑:

// untils.js
const path = require('path')
const glob = require('glob')
const PAGE_PATH = path.resolve(__dirname, '../src/pages');
exports.entries = function() {
   
 var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
 var map = {
   }
 entryFiles.forEach((filePath) => {
   
   var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
   map[filename] = filePath;
 })
 return map;
}

替换webpack.base.config.js中module.exports中的entry:

entry: untils.entries()

(二)、Output

output是一个object,里面包含一系列配置。
1、filename
output.filename配置输出文件的名称,为string类型。如果只有一个输出文件,则可以将他写为静态不变的:filename:'bundle.js';倘若有多个Chunk需要输出,需要借助模板和变量。Webpack会为每个Chunk取一个名称,所以我们可以根据Chunk的名称来区分输出的文件名:filename:'[name].js'.
2、path
output.path配置输出文件存放在本地的目录,必须是string类型的绝对路径。通常通过Node.js中的path模块去获取绝对路径:path:path.resolve(__dirname,'dist_[hashj]');
3、publicPath
output.publicPath配置发布到线上资源的URL前缀,为string类型。默认值为空字符串’’,即使用相对路径。

 output: {
   
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },

(三)、Module

1、配置Loader:rules配置模块的读取和解析规则,通常用来配置loader。其类型为数组,数组里的每一项都描述了如何处理部分文件。

  • 条件匹配:通过test、include、exclude三个配置项来选中Loader要应用规则的文件;
  • 应用规则:对选中的文件通过loader配置项来应用Loader;
 module: {
   
    rules: [
      ...(config.dev.useEslint ? [createLintingRule()] : []),
      {
   
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
   
        test: /\.js$/,   // 命中js文件
        loader: 'babel-loader',    // 使用babel-loader转换js文件
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]   // 只命中src目录下的js文件,加快webpack搜索速度
      },
      ]
      }

(四)、Resolve

Webpack在启动后会从配置的入口模块出发找出所有依赖的模块,Resolve配置Webpack如何寻找模块对应的文件。可采用默认模块化标准里的规则去查找,也可以自定义。
1、alias:resolve.alias配置项通过别名来将原导入路径映射为一个新的导入路径;
2、extensions:在导入语句没带文件后缀时,Webpack会自动带上后缀去尝试访问文件是否存在。resolve.extensions用于配置在尝试过程中用到的后缀列表。

  resolve: {
   
    extensions: ['.js', '.vue', '.json'],
    alias: {
   
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },

(五)、Plugin

用于Webpack功能扩展,plugins配置项接收一个数组,数组里的每一项都是一个要使用的Plugin的实例,Plugin需要的参数通过构造函数传入。
配置一个MPA应用的多输出扩展功能。
在utils.js中:

const HtmlWebpackPlugin = require('html-webpack-plugin');   //对每个页面单独打包生成一个新页面的插件
const merge = require('webpack-merge')
// 多页面输出配置
exports.htmlPlugin  = function() {
   
  let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
  let arr = []
  entryHtml.forEach((filePath) => {
   
    let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
    let conf = {
   
      template: filePath,
      filename: filename + '.html',
      chunks: [filename],
      inject: true
    }
    if(process.env.NODE_ENV === 'production') {
   
      conf = merge(conf, {
   
        chunks: ['manifest', 'vendor', filename],
        minify: {
   
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true
        },
        chunksSortMode: 'dependency'
      })
    }
    arr.push(new HtmlWebpackPlugin(conf))
  })
  return arr
}

在webpack.dev.conf.js中如下操作:

  plugins: [
    new webpack.DefinePlugin({
   
      'process.env': require('../config/dev.env')
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    // new HtmlWebpackPlugin({
   
    //   filename: 'index.html',
    //   template: 'index.html',
    //   inject: true,
    //   chunks: ['app']
    // }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
   
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ].concat(utils.htmlPlugin())   // 重点

学习于吴浩麟的《深入浅出Webpack》
MPA和SPA是什么?:可以看下这个哦
码云地址:如何使用vue-cli+webpack搭建一个MPA应用


转载:https://blog.csdn.net/The_upside_of_down/article/details/115794834
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场