几个维度了解webpack(一)

本文全面解析Webpack 3.10.0版本的基础配置、核心概念、使用技巧及优化手段,涵盖入口配置、输出设置、加载器、插件等功能,并详细介绍如何进行代码分割、懒加载、处理CSS文件等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

几个维度理解webpack(一)

系列文章链接:几个维度理解webpack(二)几个维度理解webpack(三)

基于的版本

  • webpack@3.10.0
  • 下载npm i webpack@3.10.0 --save-dev

webpack基础

webpack了解

环境准备
  • 命令行工具
  • 安装必须:node、webpack@3.10.0
版本
功能进化
  • 1版本:
    • 编译、打包;
    • HMR(模块化更新)
    • 代码分割
    • 文件处理
  • 2版本
    • tree shaking
    • ES module
    • 动态Import()
    • 新的文档
  • 3版本
    • Scope Hoisting(作用域提升),运行速度提升
    • Magic Comments(配合动态的import使用)

webpack概念

entry
  • 代码的入口
  • 打包的入口
  • 单个或者多个entry
    • 多页面应用程序
    • 单页面:业务代码和逻辑代码
  • entry有几种使用方法:
    • 字符串
entry:__dirname+'/src/script/main.js'
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'bundle.js'
}
  • 数组
entry:[
  __dirname+'/src/script/main.js',
  __dirname+'/src/script/a.js'
]
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'bundle.js'
}
  • 对象
entry:{
	main:__dirname+'/src/script/main.js',
	a:__dirname+'/src/script/a.js'
}
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'[name]-[hash].js'
}
//or 
output:{path:__dirname+'/dist/js',filename:'[name]-[chunkhash].js'}
Output
  • 特点
    • 打包生成的文件(bunble)
    • 一个或多个
    • 自定义规则
  • output是指打包生成的文件
  • entry中输入多个chunk时,为确保文件名唯一避免相互覆盖使用占位符命名filename;
  • 生成的名字有三种占位符
    • [name]是chunk的name;
    • [hash]是本次打包的hash值,hash值相同;
    • [chunkhash]是每个chunk的hash值,不同文件同次打包不相同,保证文件的唯一性,只有改变文件中的内容时hash才变化,未做改变的文件hash值不变;
    • [ext]是源文件的后缀名占位符
Loaders
  • 特点
    • 处理文件
    • 转化为模块
  • 常用的loader
    • 编译相关:babel-loader、ts-loader
    • 样式相关:style-loader、css-loader、less-loader、postcss-loader
    • 文件相关:file-loader、url-loader
Plugins
  • 特点
    • 参与打包整个过程
    • 打包优化和压缩
    • 配置编译时的变量
    • 极其灵活
  • 常用的Plugins
    • 优化相关:CommonsChunkPlugin、UglifyjsWebpackPlugin等
    • 功能相关:ExtractTextWebpackPlugin、HtmlWebpackPlugin、HotModuleReplacementPlugin、CopyWebpackPlugin等
名词
  • chunk代码块
  • bundle打包后的代码
  • module模块

webpack使用

  • webpack命令
    • webpack -h 查询命令
    • webpack -v 查询版本
  • webpack配置
    • 指定webpack配置文件:webpack --config webpack.config.js
  • 第三方脚手架
打包JS
  • 创建基础配置文件webpack.config.js
  • 指定配置文件名称webpack --config webpack.config.js
  • 配置文件
module.exports = {
    entry: {
        app: './app.js'
    },
    output: {
        filename: '[name].[hash:5].js'
    }
}
编译ES6/7
  • 安装npm i --save-dev babel-loader babel-core
  • babel-loader
  • babel-presets
    • 指定babel按照什么规范打包语法;
    • 一个规范的总结;
    • 设定preset的targets参数,指定编译后的需要匹配的目标:
use: {
	loader: 'babel-loader',
    options: {
	   presets: [
             ['env', {
	             'targets': {
                     'browsers': ['> 1%', 'last 2 versions']
                 }
             }]
         ]
     }
},
babel插件
  • babel polyfill、 babel runtime transform等,处理兼容的模块内的一些方法
babel polyfill
  • 全局垫片:一旦引入,全局可调用;
  • 为开发应用准备;
  • 安装npm i babel-polyfill --save
  • 引入:import 'babel-polyfill'
babel runtime transform
  • 局部垫片
  • 为开发框架准备
    • 不会污染全局
  • 安装npm i babel-plugin-transform-runtime --save-dev,npm i babel-runtime --save
  • 配置在:.babelrc文件中
TypeScript
  • 安装:npm i typescript ts-loader --save-devnpm i typescript awesome-typescript-loader --save-dev
  • 配置:tsconfig.json或者webpack.config.js
  • 配置常用选项
    • compilerOptions
    • include
    • exclude
提取共用代码
  • CommonsChunkPlugin的配置
    • name和names:chunk的名称,如果这个chunk已经在entry中定义,该chunk会被直接提取;如果没有定义,则生成一个空的chunk来提取其他所有chunk的公共代码。
    • filename:可以指定提取出的公共代码的文件名称,可以使用output配置项中文件名的占位符。未定义时使用name作为文件名。
    • chunks:可以指定要提取公共模块的源chunks,指定的chunk必须是公共chunk的子模块,如果没有指定则使用所有entry中定义的入口chunk。
    • minChunks:在一个模块被提取到公共chunk之前,它必须被最少minChunks个chunk所包含。(通俗的说就是一个模块至少要被minChunks个模块所引用,才能被提取到公共模块。)
      • 该数字必须不小于2或者不大于chunks的个数。默认值等于chunks的个数。
      • 如果指定了Infinity,则创建一个公共chunk,但是不包含任何模块,内部是一些webpack生成的runtime代码和chunk自身包含的模块(如果chunk存在的话)。
  • 优点
    • 减少代码冗余
    • 提高加载速度
  • 安装npm i
  • 配置
    • options.name or options.names
    • options.filename
    • options.minChunks
    • options.chunks
    • options.children
    • options.deepChildren
    • options.async
{
	plugins:[
		new webpack.optimize.CommonsChunkPlugin(option)
	]
}
  • 场景
    • 单页应用
    • 单页 + 第三方依赖
    • 单页 + 第三方依赖 + webpack生成代码
用webpack的CommonsChunkPlugin提取公共代码的3种方式
  • 方式一:传入字符串参数
// 默认会把所有入口节点的公共代码提取出来,生成一个common.js
new webpack.optimize.CommonsChunkPlugin('common.js')
  • 方式二:有选择的提取公共代码
//提供公共代码,默认会把所有入口节点的公共代码提取出来,生成一个common.js
// 只提取main节点和index节点
new webpack.optimize.CommonsChunkPlugin('common.js',['main','index']), 
  • 方式三:有选择性的提取(对象方式传参)
new webpack.optimize.CommonsChunkPlugin({
    name:'common', // 注意不要.js后缀
    chunks:['main','user','index']
}),
代码分割和懒加载
  • 通过写代码的规则来规定某些要代码分割;
代码分割
  • webpack内置方法
    • require.ensure参数(四个)
      • []:dependencies:引入模块,不执行
      • callback:执行引入模块
      • errorCallback:可省略
      • chunkName:接受的参数
    • require.include参数
  • ES2015的loader
    • system.import() -> import()
  • 场景
    • 分离业务代码 和 第三方依赖
    • 分离业务代码 和 业务公共代码和第三方依赖
    • 分离首次加载 和 访问后加载的代码
懒加载

处理CSS文件

引入css
style-loader
  • style-loader:创建style标签,在页面中;
    • style-loader/url:将css文件在html中变成link标签引入;
    • style-loader/useable:设置css可用不可用;
//webpack.config.js
{
	test: /\.css$/,
    use: [{
        loader: 'style-loader/useable'
    }, {
        loader: 'css-loader'
    }]
},
//app.js
import base from './css/base.css'
import common from './css/common.css'
var flag = false;
setInterval(function() {
    if (flag) {
        base.unuse();
    } else {
        base.use()
    }
    flag = !flag
}, 500)
  • style-loader的options
    • insertAt:插入的位置;
    • insertInto:插入到dom;
    • singleton:是否只使用一个style标签;
    • transform:转化,浏览器环境下,插入到页面前面;
{
	test: /\.css$/,
    use: [{
        loader: 'style-loader',
        options: {
            insertInto: '#app',
            singleton: true,
            transform: './css.transform.js'
        }
    }, {
        loader: 'css-loader'
    }]
},
css-loader
  • css-loader:是如何import一个css模块;
  • css-loader的options
    • alias:解析的别名
    • importLoader:@import
    • minimize:是否压缩
    • modules:启用css-modules
    • localIdentName:打包后的class名称;
    • getLocalIdent:保证打包后的class名称和原class名称一致;
  • 使用localIdentName:'[path][name]_[local]--[hash:base64:5]'来设置打包后的css文件中class的名称
    • path:被打包文件的路径;
    • name:被打包文件的名称;
    • local:被打包文件的class名;
{
	loader: 'css-loader',
    options: {
        minimize: true,
        modules: true,
        localIdentName: '[path][name]_[local]_[hash:base64:5]'
    }
}
css modules
  • 安装npm i postcss postcss-loader autoprefixer cssnano postcss-cssnext --save-dev
  • css-nano:优化压缩css文件,css-loader底层就是用这个;
  • Autoprefixer:自动添加css的前缀以匹配任何文件;
    • 配置
{
	loader: 'postcss-loader',
    options: {
        ident: 'postcss',
        plugins: [
            require('autoprefixer')(),
            require('postcss-cssnext')()
        ]
    }
},
  • Broswerslist指定匹配哪些浏览器

    • 所有插件都公用:package.json
    "browserslist":[
    	">=1%",
    	"last 2 versions"
    ]
    
    • 添加文件:.browserslistrc
  • postcss-import将引入的css插入到当前的css文件中;

  • postcss-url配合postcss-import使用;

配置less/sass
  • 安装npm i less-loader sass-loader less node-sass --save-dev
提取css代码
  • 方法一:extract-loader
  • 方法二:使用ExtractTextWebpackPlugin(推荐)
    • 安装npm i extract-text-webpack-plugin --save-dev
    • 配置
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
//配置插件
plugins: [
	 new ExtractTextWebpackPlugin({
        filename: '[name].min.css',
        allChunks: false
    }),
    new PurifyCSS({
        paths: glob.sync([
            path.join(__dirname, './*.html'),
            path.join(__dirname, "./src/*.js")
        ])

    }),
    //Tree Shaking不使用的代码不打包
    new webpack.optimize.UglifyJsPlugin()
]
//配置loader
{
	test: /\.less$/,
    use: ExtractTextWebpackPlugin.extract({
        fallback: {
            loader: 'style-loader',
            options: {
                singleton: true,
                transform: './css.transform.js'
            }
        },
        use: [{
            loader: 'css-loader',
            options: {
                // 压缩
                minimize: true,
                modules: true,
                localIdentName: '[local]',
            }
        }, {
            loader: 'less-loader'
        }]
    })
}
  • 生成app.min.css文件后是不会自动加载进入index.html中的,需要我们手动加载进去。
<link rel="stylesheet" href="./dist/app.min.css">

Tree Shaking

  • 不使用的代码不打包进入;
  • 包括:JS Tree Shaking和CSS Tree Shaking
  • 使用场景
    • 常规优化
    • 引入第三方库的某一个功能
JS Tree Shaking
  • 使用插件帮助:Webpack.optimize.uglifyJS
var webpack = require('webpack')
new Webpack.optimize.UglifyJsPlugin()
CSS tree shaking
  • 使用purifycss-webpack
    • 安装 npm i purifycss-webpack glob-all purify-css --save-dev
    • 配置
      • path:glob.sync([])
  • 使用glob-all处理多路径
var PurifyCSS = require("purifycss-webpack");
new PurifyCSS({
	 paths: glob.sync([
        path.join(__dirname, './*.html'),
        path.join(__dirname, "./src/*.js")
    ])
}),

文件处理

  • 处理文件内容
    • 图片文件
    • 字体文件
    • 第三方JS库
图片处理
  • css中引入的图片的处理
    • 自动合成雪碧图
    • 压缩图片
    • Base64编码
  • 使用:file-loader,url-loader,img-loader,postcss-sprites
  • 安装npm i file-loader url-loader img-loader postcss-sprites --save-dev
  • 图片打包的配置
//
{
	test: /\.(jpg|img|png|gif|svg|jpeg)$/,
    use: [{
         loader: 'file-loader',
         options: {
             publicPath: '',
             //outputPath: '',
             //将打包生成的文件关联原文件夹
             useRelativePath: true
         }

		//如果想根据图片大小来进行打包,可以这样设置
		loader: 'url-loader',
        options: {
        //当图片大小小于限制时会自动转成 base64 码引用
            limit: 200
        }
    }]
}

//注意,输出的路径要将dist/注掉,不然打包出来的文件路径会多出来一层dist/
 output: {
	path: path.resolve(__dirname, 'dist'),
    //publicPath: 'dist/',
    filename: '[name].bundle.js',
    //chunkFilename: '[name].chunk.js'
},
  • 图片合成雪碧图的配置
//在postcss-loader的配置中引入postcss-sprites,进行设置
{
	//处理css文件
    loader: 'postcss-loader',
    options: {
        ident: 'postcss',
        plugins: [
            //打包生成雪碧图的配置
            require('postcss-sprites')({
                //雪碧图打包后的地址
				spritePath: 'dist/assets/imgs/sprites',
                //适应高分辨率视口
                retina: true
            }),
            //require('autoprefixer')(),
            require('postcss-cssnext')()
        ]
    }
}

//修改雪碧图的名字
{        
	loader: 'url-loader',
    options: {
        name: '[name]-min.[ext]',
        limit: 200,
        //publicPath: '',
        //outputPath: '',
        //将打包生成的文件关联原文件夹
        useRelativePath: true
    }
},
字体文件
  • 字体文件后缀名
    • eot,woff2,ttf,svg
{
	test:/\.(eot|woff2?|ttf|svg)$/,
	use:[
		{
			loader:'url-loader',
			options:{
				name: '[name]-min.[ext]',
                limit: 200,
                //将打包生成的文件关联原文件夹
                useRelativePath: true
			}
		}
	]
}
  • fa-loader
第三方JS库
  • 方法一:使用webpack.providePlugin插件
    • 使用npm下载第三方插件后的配置
//通过npm下载的第三方插件后,使用配置信息进行配置
new webpack.ProvidePlugin({
	$:'jquery'
})
- 使用本地第三方js文件的配置:
//将第三方js文件放入进入本地的文件夹,使用script标签进行引入。
//插入resolve
resolve:{
	alias: {
		//$代表精确匹配
		jquery$:path.resolve(__dirname, 'src/libs/jquery.min.js')
		//src/libs/jquery.min.js里面放着jquery
}
  • 方法二:使用imports-loader
    • 安装 npm i imports-loader
{
	test:path.resolve(_dirname,'src/app.js');
	use:[
		{
			loader:'imports-loader',
			options:{
				$: 'jquery'
			}
		}
	]
}
  • 方法三:window对象

处理HTML文件

  • 自动生成HTML
  • 场景优化
生成HTML
  • htmlwebpackplugin参数
    • template
    • filename
    • minify
    • chunks
    • inject
  • 安装npm i html-webpack-plugin --save-dev
  • 配置:
var htmlWebpackPlugin = require('html-webpack-plugin')

//处理html在plugin中
new htmlWebpackPlugin({
    filename: 'index.html',
    template: './index.html',
    //inject: false,
    chunks: ['app'],
    //压缩html文件
    minify: {
        //消除空格
        collapseWhitespace: true
    }
})
html中引入的图片
  • 使用html-loader,安装npm i html-loader --save-dev
  • html-loader的options
    • attrs: [img:src];
{
	test: /\.html$/,
    use: [{
        loader: 'html-loader',
        options: {
            attrs: ['img:src', 'img:data-src']
        }
    }]
}

//url-loader中配置修改
{     
   //引入图片的处理
    loader: 'url-loader',
    options: {
        name: '[name]-min.[ext]',
        limit: 20,
        //publicPath: '',
        outputPath: 'assets/imgs/',
        //将打包生成的文件关联原文件夹,就是原文件夹的位置和包裹关系和打包后的一样
        //useRelativePath: true
    }
}
配合优化
  • 提前载入webpack加载代码:
    • inline-manifest-webpack-plugin在和html-loader配合时有bug(不推荐);
    • html-webpack-inline-chunk-plugin(推荐)
  • 安装npm i html-webpack-inline-chunk-plugin --save-devnpm i babel-core babel-loader babel-preset-env --save-dev
  • 配置:
//loader中:
{
	test: /\.js$/,
    use: {
        'loader': 'babel-loader',
        'options': {
	        presets: ['env']
        }
    },
    exclude: '/node_modules/'
}

//plugin中
//提取公共代码的插件
new webpack.optimize.CommonsChunkPlugin({
    //公共模块打包后的名称
    name: 'manifest',
    //指定被引入几次的代码会被打包
    minChunks: 2,
    chunks: ['pageA', 'pageB']
}),
new HtmlInlinkChunkPlugin({
    inlineChunks: ['manifest']
}),

//修改htmlWebpackPlugin配置
//处理html
new htmlWebpackPlugin({
    //取消这个
    //chunks: ['app'],
}),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值