Webpack

Webpack打包原理

webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。

webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。

webpack做的就是分析代码,转换代码,编译代码,输出代码。webpack本身是一个node的模块,所以webpack.config.js是以commonjs形式书写的(node中的模块化是commonjs规范的)

webpack中每个模块有一个唯一的id,是从0开始递增的。整个打包后的bundle.js是一个匿名函数自执行。参数则为一个数组。数组的每一项都为个function。function的内容则为每个模块的内容,并按照require的顺序排列。

提升webpack 的构建速度

减少resolve 的解析
i. 使用绝对路径指定node_modules,不做过多查询

ii. 删除不必要的后缀自动补全,少了文件后缀的自动匹配,即减少了文件路 径查询的工作

iii. 避免新增默认文件,编码时使用详细的文件路径,代码会更容易解读,也 有益于提高构建速度

把loader 应用的文件范围缩小
i. 我们在使用loader 的时候,尽可能把loader 应用的文件范围缩小,只 在最少数必须的代码模块中去使用必要的loader,例如node_modules 目录下的其他依赖类库文件,基本就是直接编译好可用的代码,无须再经过 loader 处理了

减少plugin 的消耗
i. webpack 的plugin 会在构建的过程中加入其它的工作步骤,如果可以的话,适当地移除掉一些没有必要的plugin。

webpack 是一个模块打包器

1.下载全局webpack,使用webpack命令 2.下载全局webpack-cli 3.新建一个配置文件,默认的文件名 webpack.config.js

webpack的四大核心概念

入口(entry)

mode:"development",
entry : String | Array | Object 前两种是单入口文件使用,object是多入口文件使用

entry:path.join(__dirname,"./src/index.js") 单入口
ebtry:{ 多入口
    index:path.join(__dirname,"./src/index.js"),
    app:path.join(__dirname,"./src/app.js")
}

出口(output)

编译之后默认是在 dist 文件夹下 main.js文件

output:{

path:path.join(__dirname,'dist'),编译之后的输出路径

 filename:"[name].js"; 编译之后的文件名称,默认是main.js
}

加载器(loader)

module:{

rules:[
{
    test:/\.(js | jsx)$/,
    loader:"babel-loader",
    options:{
        "presets":['@babel/presets-env']
    }
},{
    test:/\.css$/,
    use:['style-loader','css-loader']
},{
    test:/\.(jpg|jpeg|git|png)$/,
    loader:"url-loader",
    optios:{ 
        limit:4000,
    }
},{
    test:/\.(eot|svg|ttf|woff)$/,
    loader:"file-loader" 小文件类型
    options:{
        name:"./font/[name].[ext]"
    }
},{
    test:/\.scss$/,
    use:ExtractTextWebpackPlugin.extract({
        fallback:"style-loader",
        use:['css-loader','sass-loader']
    })
    use:['style-loader','css-loader','sass-loader'],
}
]
}

插件(plugins)

抽离 css
下载extract-text-webpack-plugin
需要下载下一个版本 extract-text-webpack-plugin@next

2. 引入插件
3. 调用插件
4. 使用插件
    plugins:[
        new ExtractTxtWebpackPlugin('style.css')
        抽离之后的 css 文件
        new CleanWebpackPlugin(), 清除
        new HtmlWebpackPlugin({ 自动生成 同级 虚拟的html
            template:"index.html",要编译的模板
            filename:""编译后的默认名字
            title:"",编译后的默认的名字
            <%= HtmlWebpackPlugin.options.title %>
            inject:true, 是否注入js css 默认属性
            minify:{
                removeAttributeQuotes:true, 去除引导
                collapseWhitespace:true,去除空格
                removeComments:true,去除注释
                removeEmptyAttributes:true,去除空属性
                
            }
        }),
        new webpack.HotModuleReplacementPlugin() 默认热更新
    ]

    devServer:{ 开发
        port:8080,
        open:true,
        hot:true,
        host:'localhost',
        before(app){ middleware 中间件
            app.get('/api/list',(req,res,next)=>{
                res.send({code:1,data:list})
            });
        },
        proxy:{ 代理 gulp
            '/classify/iconlist':"http:loclahost:3000",
        },
        resolve:{
            alias:{
                
            }
        }
    }

webpack 一些指令

–config 指定配置文件路径

–watch 实时监听更新

–progress 进度条

–mode production\development

在package.json文件的scripts写执行指令

"scripts": {

"build": "webpack --config webpack.dev.js --mode production",
"dev":"webpack-dev-server --config webpack.dev.js --mode development"
},

webpack 工作的主要流程和其中几个重要的概念

Compiler,webpack 的运行入口,实例化时定义webpack 构建主要流程,同时创建 构建时使用的核心对象compilation

Compilation,由Compiler 实例化,存储构建过程中各流程使用到的数据,用于控 制这些数据的变化

Chunk,即用于表示chunk 的类,对于构建时需要的chunk 对象由Compilation 创 建后保存管理

Module,用于表示代码模块的类,衍生出很多子类用于处理不同的情况,关于代码模 块的所有信息都会存在Module 实例中,例如dependencies 记录代码模块的依赖等

Parser,其中相对复杂的一个部分,基于acorn 来分析AST 语法树,解析出代码模 块的依赖

Dependency,解析时用于保存代码模块对应的依赖使用的对象

Template,生成最终代码要使用到的代码模板,像上述提到的胶水代码就是用对应的 Template 来生成

工具类问题

1,webpack打包的配置,常见的loaders和plugins?

2,webpack的基本配置有哪些?

Entry 配置模块的入口;

Output 配置如何输出最终想要的代码;

Module 配置处理模块的规则;

Resolve 配置寻找模块的规则;

Plugins 配置扩展插件;

DevServer 配置DevServer;

3,webpack 打包按需加载?

在webpack 的构建环境中,要按需加载代码模块很简单,遵循ES 标准的动态加载语 法dynamic-import 来编写代码即可,webpack 会自动处理使用该语法编写的模块: 需要我们在webpack 配置中添加一个output.chunkFilename 的配置:

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash:8].js',
    chunkFilename: '[name].[hash:8].js' // 指定分离出来的代码文件的名称
}

4,webpack配置开发环境和生产环境的区别?

日常的前端开发工作中,一般都会有两套构建环境:一套开发时使用,构建结果用于 本地开发调试,不进行代码压缩,打印debug 信息,包含sourcemap 文件;另外一套 构建后的结果是直接应用于线上的,即代码都是压缩后,运行时不打印debug 信息,静态文件不包括sourcemap 的。有的时候可能还需要多一套测试环境,在运行时直接 进行请求mock 等工作。

webpack 4.x版本在webpack配置中有mode选项可以直接配置production 或development

webpack 3.x 一般是通过node命令传递环境变量,来控制不同环境下的构建行为

如:
{
    "scripts": {
    "build": "NODE_ENV=production webpack",
    "dev": "NODE_ENV=development webpack-dev-server"
    }
}

然后在webpack.config.js 文件中可以通过process.env.NODE_ENV 来获取命令传入的环 境变量:

常见的环境差异配置

生产环境可能需要分离CSS

成单独的文件,以便多个页面共享同一个CSS 文件

生产环境需要压缩HTML/CSS/JS 代码

生产环境需要压缩图片

开发环境需要生成sourcemap 文件

开发环境需要打印debug 信息

开发环境需要live reload 或者hot reload 的功能 以上是常见的构建环境需求差异,可能更加复杂的项目中会有

更多的构建需求(如划 分静态域名等),但是我们都可以通过判断环境变量来实现这些有环境差异的构建需 求。

webpack 4.x 的mode 已经提供了上述差异配置的大部分功能,mode 为production 时默 认使用JS 代码压缩,而mode 为development 时默认启用hot reload,等等。这样让我 们的配置更为简洁,我们只需要针对特别使用的loader 和plugin 做区分配置就可以 了。

webpack 3.x 版本还是只能自己动手修改配置来满足大部分环境差异需求。

5,webpack热加载的原理, 介绍一下HMR?

HMR 全称是Hot Module Replacement,即模块热替换。在这个概念出来之前,我们使

用过Hot Reloading,当代码变更时通知浏览器刷新页面,以避免频繁手动刷新浏览器 页面。HMR 可以理解为增强版的Hot Reloading,但不用整个页面刷新,而是局部替 换掉部分模块代码并且使其生效,可以看到代码变更后的效果。所以,HMR 既避免了 频繁手动刷新页面,也减少了页面刷新时的等待,可以极大地提高前端页面开发效率. 在webpack中用法很简单

HMR 是webpack 提供的非常有用的一个功能,跟我们之前提到的一样,安装好webpack-dev-server, 添加一些简单的配置,即在webpack 的配置文件中添加启用

HMR 需要的两个插件:

const webpack = require('webpack')
    module.exports = {
    // ...
        devServer: {
            hot: true // dev server 的配置要启动hot,或者在命令行中带参数开启
        },
        plugins: [
       
        new webpack.NamedModulesPlugin(),  用于启动HMR 时可以显示模块的相对路径
       
         new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件
    ],
}
5,webpack提取公共模块?

webpack 3.x 以前的版本是使用CommonsChunkPlugin 来做代码分离的,

webpack 4.x 则是把相关的功能包到了optimize.splitChunks 中,直 接使用该配置就可以实现代码分 离。

webpack4

显式配置共享类库可以这么操作:

module.exports = {
    entry: {
        vendor: ["react", "lodash", "angular", ...], // 指定公共使用的第三方类库
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    chunks: "initial",
                    test: "vendor",
                    name: "vendor", // 使用vendor 入口作为公共部分
                    enforce: true,
                },
            },
        },
    },
    // ... 其他配置
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值