第三节:webpack基本参数配置

一.Entry参数配置

1.环境搭建

首先文件目录如下:

image-20200423185943801

add.js文件:

function add (a, b){
  return a + b;
}

export default add;

count.js文件:

function count(x, y){
  return x + y;
}

export default count;

index.js文件:

import add from './add'
import count from './count'

console.log('index.js文件加载了~');

console.log(add(1, 2));
console.log(count(3, 5));

webpack.config.js的配置:

const { resolve } = require('path') 
const HtmlWebpackPlugin = require('html-webpack-plugin')

/**
 * entry:入口起点
 * 1.string
 * 2.array
 * 3.object
 */

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: 'development'
}

2.entry写法

string

entry: './src/index.js'

属于单入口写法,打包形成一个chunk,输出一个bundle文件;这种写法打包出来的js文件默认叫main.js

image-20200423190831339

array

entry: ['./src/index.js', './src/add.js'],

属于多入口写法,所有入口文件最终只会形成一个chunk,输出出去只有一个bundle文件。

为了演示,删除index.js中引入add.js的语句:

// import add from './add'
import count from './count'

console.log('index.js文件加载了~');

// console.log(add(1, 2));
console.log(count(3, 5));

当引入多个js文件之后,所有的文件都会打包到第一个文件中,也就是index.js。并且输出的bundle文件默认名字为main.js

image-20200423191510747

作用:只有在HMR功能中让html热更新生效;

object

  entry: {
    index: './src/index.js',
    add: './src/add.js'
  },

属于多入口写法,有几个入口文件就形成几个chunk,并输出相应数量的bundle文件;

此时chunk的名称 是key

image-20200423192139199

特殊用法

value设置为数组以第二种方式引入多个入口js文件:

  entry: {
    Pindex: ['./src/index.js', './src/count.js'],
    Padd: './src/add.js'
  },

同时将index.js中的引入全部删除:

// import add from './add'
// import count from './count'

console.log('index.js文件加载了~');

// console.log(add(1, 2));
// console.log(count(3, 5));

这种方式为结合了arrayobject两种形式,在Pindex中,将数组中的所有js文件都打包进第一个js文件:index.js中,形成一个chunk,输出的bundle文件名字为指定的Pindex.jsPadd则按原来object的形式输出。也就是最后打包出Pindex.jsPadd.js两个文件,并且Pindex.js包含了index.jscount.js两个文件:

image-20200423192923571

这种方式结合和array写法和object写法的功能:

  entry: {
    //所有入口文件最终只会形成一个chunk,输出出去只有一个bundle文件
    Pindex: ['./src/index.js', './src/count.js'],
    //形成一个chunk,输出一个bundle文件
    Padd: './src/add.js'
  },

这种方式多用于dll引入时:

  entry: {
    //最终打包生成的[name] --> jquery
    //['jquery] --> 要打包的库是jquery
    jquery: 'jquery',
    react: ['react', 'react-dom', 'react-router'],
  },

二.Output参数配置

output的基本写法:

  output: {
    //文件名称(指定名称和目录)
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build'),
    publicPath: '/',
    chunkFilename: 'js/[name]_chunk.js',
    library: '[name]',
    //libraryTarget: 'window',
    libraryTarget: 'commonjs'
  },

其中:

1.filename

文件名称,可以指定名称和目录;

2.path

输出文件目录,该目录为将来所有资源输出的公共目录;build只是指定了根目录,输出的文件可以带有目录结构,但都是以build为根目录;

3.publicPath

所有资源引入公共路径的前缀。比如会将imgs/a.jpg转换为/imgs/a.jpg;前者表示当前路径下直接找imgs,后者的/会以当前服务器的地址作为补充,去服务器根目录下找imgs目录;代码上线的时候更倾向于使用后者这样的路径;所以会通过publicPath配置一个公共的路径;

注意这个参数,不是指定输出的路径,而是设置引入路径的格式:

不使用了该配置,文件的引入路径前面没有/

image-20200423200630022

使用该配置后,就有/

image-20200423200658376

该参数一般用于生产环境

4.chunkFilename

非入口chunk的名称。所谓入口chunk,指的是上面讨论的单入口和双入口chunk的引入方式,除此之外的引入方式,比如import等引入方式,都采用这种方式;

比如使用import方式引入add.js文件时,入口文件index.js文件应该这样改写:

import count from './count'

console.log('index.js文件加载了~');

import ('./add').then(({default: add}) => {
  console.log(add(1, 2));
}) 

console.log(count(3, 5));

执行webpack后,add.js被整改为了0_chunk.js

image-20200424142503368

采用这种写法,可以将某些文件打包输出为单独的chunk

5.library

没有使用该字段时,打包出来的main.js内容都是被包围在函数中的,外面访问不了:

image-20200424142913841

而添加了该字段后,打包出来的main.js代码通过赋值给一个全局变量mainmain为打包过后整个库向外暴露的变量名。

image-20200424143145688

可通过libraryTarget属性指定这个全局变量的所属,比如将它设置为window对象的属性:

image-20200424143451566

比如我想以commonjs的方式引入该全局变量,那么可以将libraryTarget的值设置为commonjs,打包后的结果为:

image-20200424143757278

这样就可以commonjs的方式引入这个全局变量了;

总结:也就是通过libraryTarget这个属性,将打包后的库文件暴露出去,外面可以直接引入使用。并且可以设置引入的规则,比如windowcommonjs等方式;

library一般是作为暴露一个库来使用的,通常是结合dll将某个库单独打包,然后引入使用,这时候才需要使用library

三.module参数配置

module参数里主要配置loader

const { resolve } = require('path') 
const HtmlWebpackPlugin = require('html-webpack-plugin')


module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build'),
  },
  module: {
    rules: [
      //loader的配置
      {
        test: /\.css$/,
        //多个loader使用use
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.js$/,
        //配出node_modules下的js文件
        exclude: /node_modules/,
        //只检查src 下的js文件
        include: resolve(__dirname, 'src'),
        //优先执行pre
        // enforce: pre,
        //延后执行post,不写就是按顺序执行
        enforce: post,
        //单个loader用loader
        loader: 'eslint-loader',
        //单个loader时,还可以加一个options进行具体配置
        options: {}
      },
      {
        //表示oneOf中的配置只生效一个
        oneOf: [

        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: 'development'
}

四.Resolve参数配置

该参数作用为配置解析模块的规则:

  //解析模块的规则
  resolve: {
    //配置解析模块路径别名
    alias: {
      //意思是配置了一个变量$css,它的值就代表了这个css文件的绝对路径
      $css: resolve(__dirname, 'src/css')
    },
    extensions: ['.js', '.json', '.css']
  }

1.alias属性

比如可以通过其中的alias属性配置文件的路径,因为当项目文件目录较深的时候,引用的路径会比较麻烦。

经过上面的配置后,$css就代表了src/css这个路径,在index.js文件中就可以通过下列形式引入src/css/index.css文件了:

import '$css/index.css'

这样做的优点是,只需要进行一次设置,之后需要引入文件时就可以简写路径。缺点:写路径的时候就没有提示了。

2.extensions属性

作用为:配置文件路径中可以省略的后缀名,默认值为jsjson,也就是说引入src下的index.js时,引入路径可以省略js后缀,即'./src/index'

如在index.js中引入文件:

import '$css/index'

首先会找到src/css目录,然后查找有没有index.jsindex.jsonindex.css文件,如果有就引入,没有就报错;这样写的缺点是:千万不要将同名的不同类型的文件同时省略后缀名,比如index.jsindex.css,这样通过index引入始终只能引入index.js

3.modules属性

作用为:告诉webpack解析模块是去找哪个目录

五.DevServer参数配置

具体配置项如下所示:

  devServer: {
    //运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    //监视contentBase目录下的所有文件,一旦文件变化就会reload(重载)
    watchContentBase: true,
    watchOptions: {
      //忽略文件
      ignored: /node_modules/
    },
    //启动gzip压缩
    compress: true,
    //指定端口号
    port: 5000,
    //指定域名
    host: 'localhost',
    //自动打开浏览器
    open: true,
    //开启HMR功能
    hot: true,
    //不要显示启动服务器的日志信息
    clientLogLevel: 'none',
    //除了一些基本的启动信息之外,其他内容都不要打印
    quiet: true,
    //如果出错了,不要全屏提示
    overlay: false,
    //服务器代理--> 解决开发环境的跨域问题
    proxy: {
      //一旦devServer(5000)服务器接收到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000);
      '/api': {
        target: 'http://localhost:3000',
        //发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }

六.Optimization参数配置

该配置需要在生产环境production下使用;

  optimization: {
    splitChunks: {
      chunks: 'all',
      //以下为默认值,可以不写
      /* minSize: 30 * 1024, //分割的chunk最小为30KB
      maxSize: 0,//0表示最大没有限制
      minChunks: 1,//要提取的chunks最少被引用1次
      maxAsyncRequests: 5,//按需加载时,并行加载的文件最大数量为5
      maxInitialRequests: 3,//入口js文件最大并行请求数量最大为3
      automaticNameDelimiter: '~',//设置名称连接符为~
      name: true,//可以使用命名规则
      cacheGroups: {//分割chunk的组
      //node_modules中的文件会被打包到vendors 组的chunk中 -->名称格式为: vendors~xxx.js(上面设置了连接符为~)
        //满足上面的公共规则,如:大小要超过30KB,至少被引用一次;
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          //打包的优先级
          priority: -10
        },
        default: {
          //要提取的chunk最少被引用2次
          minChunks: 2,
          //优先级
          priority: -20,
          //如果当前要打包的模块和之前已经被提取的模块是同一个,就会复用,而不会重新打包模块
          reuseExistingChunk: true
        }
      } */
    },
  //将当前模块的记录其他模块的hash单独打包为一个文件runtime
  //解决缓存失效问题:修改a文件导致b文件的contenthash变化
  runtimeChunk: {
    name: entrypoint =>`runtime-${entrypoint.name}`
  },
  //配置生产环境的压缩方案:js和css
  minimizer: [
    new TerserWebpackPlugin({
      //开启缓存
      cache: true,
      //开启多进程打包
      parallel: true,
      //启动source-map
      sourceMap: true
    })
  ]
  }

1.splitChunks

提取公共代码,作为单独chunk进行打包;

2.runtimeChunk

解决修改一个文件导致另外一个文件的缓存失效的问题;

3.minimizer

配置生产环境jscss的压缩方案:terser插件
首先需要全局下载:

npm i terser-webpack-plugin -D

然后在webpack.config.js中引用该库:

cosnt TerserWebpackPlugin = require('terser-webpack-plugin')

使用:

  //配置生产环境的压缩方案:js和css
  minimizer: [
    new TerserWebpackPlugin({
      //开启缓存
      cache: true,
      //开启多进程打包
      parallel: true,
      //启动source-map
      sourceMap: true
    })
  ]
posted @ 2020-09-03 22:58  AhuntSun  阅读(754)  评论(0编辑  收藏  举报