webpack4基本知识梳理

前言:最近有空看了看webpack5,干脆把webpack4仔细整理下。
webpack是用common.js,加上用到了node的基本知识点。先整理一部分基础,后续补充webpack性能优化,以及基础配置之上的详细配置。

webpack五个核心概念

先了解下webpack的基本核心配置,了解下这主要的五个核心概念,对webpack有个整体的概念,慢慢我们再来根据一个个需求,问题,逐级进阶。


 1. entry 入口文件
 2. output 打包的文件绝对路径
 3. loader 资源转换器
 4. plugins 插件
 5. mode 环境模式,分生产环境,开发环境

//webpack.config.js

const {resolve} = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const commonCssLoader = [
	//'style-loader',
	MiniCssExtractPlugin.loader,//取代style-loader,提取js中css成单独文件
	//可以用mini-css-extract-plugin把css提取出来,那就不需要style-loader,
	'css-loader',
	{
	loader:'postcss-loader',//处理css的兼容性
	options:{
	ident:'postcss',
	plugins:()=>[
	//postcss的插件
	require('postcss-preset-env')()
	]}
	];
module.exports={
	entry:'./src/index.js',//就是写你的项目入口文件
	output:{
	filename:"built.js",//生成目录如何可以根据自己需要配置:js/built.js
	path:resolve(__dirname,"build") //__dirname是获取node的绝对地址
	},
	module:{
	rules:[
	//loader的配置
	{
	test:/\.js$/,
	exclude:/node_modules/,//把模块包排除
	enforce:'pre',//优先执行,避免和下面的兼容性loader冲突
	use: ['babel-loader?cacheDirectory=true'],
	options:{
		fix:true //自动修复
	}
	},
	{
      test: /\.js$/,
      use: ['babel-loader?cacheDirectory=true'],
      include: path.join(__dirname, '../src'),
      exclude:/node_modules/,
      options:{
      //预设:指示babel做怎么样的兼容性处理
      presets:[ [
      '@babel/preset-env',
      {
      //按需加载就不需要第3步的加 "@babel/polyfill" 
        "useBuiltIns": "usage",
        /**
        * false : 不启用polyfill, 如果 import '@babel/polyfill', 会无视 browserlist 将所有的 polyfill 加载进来
           entry : 启用,需要手动 import '@babel/polyfill', 这样会根据 browserlist 过滤出 需要的 polyfill
           usage : 不需要手动import '@babel/polyfill'(加上也无妨,构造时会去掉), 且会根据 browserlist +,无法支持IE
        */
        "corejs": {
	        version:3,//指定core-js版本
	        //指定兼容性做到那个版本的浏览器
	        targets:{
	        chrome:'60',
	        firfox:'60',
	        ie:'9',
	        safari:"10",
	        edge:"17"
	        }
        }
      }
    ],]
    }
	},
	{
	//处理css资源
	test:/\.css$/,
	use:[...commonCssLoader],
	},
	{
	//处理less资源
	test:/\.less$/,//正则匹配资源
	use:[
		//'style-loader',//把css字符串创建style标签插入到head中
		//'css-loader',//把css转换成字符串,整合到js文件中。
		...commonCssLoader,//代码复用,
		 {
          loader: 'less-loader',
          options: {
             modules: true,
             javascriptEnabled: true,
             localIdentName: '[local]--[hash:base64:5]',//样式文件复用,避免class名重复出现问题
              }
                },          
		]//把less转换成css
	},
	{
	//处理图片资源
	test:/\.(jpg|png|gif|jpeg)/,
	loader:'url-loader',
	//url-loader是在file-loader的基础上的一个补充,可以将图片转成base64是专门针对图片的,所以安装npm包的时候,要下载url-loader file-loader。
	//url-loader这个loader是指处理样式和js里面的图片处理,对于html里面引入的图片不起作用,所以还需要html-loader。
	options:{
	limit:8 * 1024,//8kby以下转成base64码
	name:'[hash:10].[ext]',//hash值和ext值是打包运行就会生成的,在命令终端可以看到,各项资源打包的详细数据,有类型,size等等。
	outputPath:'images',//输出路劲配置
	//关闭es6模块化
	esModule:false
	}},
	{
	//处理html中img资源
	test:/\.html$/,
	loader:'html-loader' 
	//因为这个html-loader处理图片资源是用commonJs去解析,而上面url-loader是根据es6去解析,所以要关闭url-loader的es6模块化
	},{
	//处理其他资源
	exclude:/\.(html|css|less|jpg|png|jpeg|gif)/,
	loader:'file-loader',//直接将资源处理输出
	}
	]
	},
	plugins:[
	//plugins的配置
	new HtmlWebpackPlugin({
	template:'./src/index.html',//生成html的时候可以用自己配置的html模板,如果在html页面有设置全局变量就可以不用每次部署都要替换。
	}),
	new MiniCssExtractPlugin(),//提取css文件
	new OptimizeCssAssetsPlugin() //压缩css文件
	],
	mode:"development",//production 会自动压缩js代码
}

热更新

	// webpack-dev-server
    // contentBase: path.join(__dirname, '../dist'), 
    // 注:contentBase一般不配,主要是允许访问指定目录下面的文件,这里使用到了dist下面的index.html
   devServer: {
        // contentBase: path.join(__dirname, '../dist'),
        compress: true,  // gzip压缩
        host: 'localhost', // 允许ip访问
        hot: true, // 热更新
        historyApiFallback: true, // 解决启动后刷新404
        port: 9000,// 端口
        proxy: { // 配置服务代理
            '/api': {
                target: 'http://localhost:8002',
                pathRewrite: {'^/api': ''},  //可转换
                changeOrigin: true,  //解决跨域的问题
            }
        }
    },

html代码压缩

	new HtmlWebpackPlugin({
		template:'./src/index.html',
		//压缩代码处理
		minify:{
		//移除空格
		collapseWhitespace:true,
		//移除注释
		removeComments:true}
	
	}),

css兼容性处理、单独打包、压缩样式css

css兼容性处理  :
 1. postcss  ==> 安装postcss-loader postcss-preset-env
 2. package.json中设置browserslist  :  GitHub上有browserslist的详细配置。
  "browserslist": {
  //这里的环境变量指的是node中的环境变量,所以process.env.NODE_ENV = 'development'
  'development':[
    "> 1%",
    "last 2 versions"
  ],
  //默认是生产环境
  'production':[
	"> 1%",
	"not dead",//死掉的浏览器,太低版本的ie
	"not op_mini_all",//欧朋浏览器。。。。
	]}
	
 3. webpack.config.js中loader配置
{
	//处理css资源
	test:/\.css$/,
	use:[
	//'style-loader',
	MiniCssExtractPlugin.loader,//取代style-loader,提取js中css成单独文件
	//可以用mini-css-extract-plugin把css提取出来,那就不需要style-loader,
	'css-loader',
	{
	loader:'postcss-loader',
	options:{
	ident:'postcss',
	plugins:()=>{
	//postcss的插件
	require('postcss-preset-env')()
	}}}
	],
	},
压缩css
webpack.config.js中plugins配置

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
plugins:[
 new OptimizeCssAssetsPlugin()
 ]
提取css文件,单独打包
 /**
     * hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值
     chunkhash和hash不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。
     contenthash是针对文件内容级别的,只有你自己模块的内容变了,那么hash值才改变,所以我们可以通过contenthash解决上诉问题
  */
  plugins:[
	new MiniCssExtractPlugin({
		filename: "static/[name].[contenthash].css",
		chunkFilename: "static/[id].[contenthash].css"
	})
	]

语法eslint检查


 1. eslint ===> 安装eslint eslint-loader
 2. package.json中eslintConfig设置规则
 "eslintConfig":{
 	"extends":"airbnb-base"
 }
 3. 推荐使用airbnb ===> 安装 eslint-config-airbnb-base eslint-plugin-import
 4. loader配置
	{
	test:/\.js$/,
	exclude:/node_modules/,//把模块包排除
	loader:"eslint-loader",//eslint 语法检查
	options:{
	fix:true //自动修复eslint的错误
	}
	},

js兼容性处理

/*src目录下面的以.js结尾的文件,要使用babel解析*/
/*cacheDirectory是用来缓存编译结果,下次编译加速*/
1. 基本兼容处理:安装babel-loader @babel/core @babel/preset-env    ,问题:只能转换基本语法,如高级语法promise就转换不了
2. loader配置
{
      test: /\.js$/,
      use: ['babel-loader?cacheDirectory=true'],
      include: path.join(__dirname, '../src'),
      exclude:/node_modules/,
      options:{
      //预设:指示babel做怎么样的兼容性处理
      presets:['@babel/preset-env']
      }
},

3. 全部兼容性处理  ,问题:所有兼容性代码都会引入,导致体积太大
 entry: {
        app: [
            "@babel/polyfill", //全面的js兼容性处理,按需加载时去掉
            path.join(__dirname, '../src/index.js')
        ],
        vendor: ['react', 'react-router-dom', 'redux', 'react-dom', 'react-redux'] 
        //vendor的意思是依赖的第三方库,不会经常变更的
    },
4.按需加载 coreJs   安装core-js    推荐!!!
{
      test: /\.js$/,
      use: ['babel-loader?cacheDirectory=true'],
      include: path.join(__dirname, '../src'),
      exclude:/node_modules/,
      options:{
      //预设:指示babel做怎么样的兼容性处理
      presets:[ [
      '@babel/preset-env',
      {
      //按需加载就不需要第3步的加 "@babel/polyfill" 
        "useBuiltIns": "usage",
        /**
        * false : 不启用polyfill, 如果 import '@babel/polyfill', 会无视 browserlist 将所有的 polyfill 加载进来
           entry : 启用,需要手动 import '@babel/polyfill', 这样会根据 browserlist 过滤出 需要的 polyfill
           usage : 不需要手动import '@babel/polyfill'(加上也无妨,构造时会去掉), 且会根据 browserlist +,无法支持IE
        */
        "corejs": {
	        version:3,//指定core-js版本
	        //指定兼容性做到那个版本的浏览器
	        targets:{
	        chrome:'60',
	        firfox:'60',
	        ie:'9',
	        safari:"10",
	        edge:"17"
	        }
        }
      }
    ],]
    }
},

ps:babel的配置内容可以单独拉出来一个文件维护  在src同级创建一个   .babelrc的文件 ,内容是一样的
{
"presets":[],
"plugins":[]
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值