webpack的个人理解(一)

一、构建工具的介绍

关于构建工具,我用过的也就webpack,gulp稍微有些了解,但是没在项目中真正用到。以我的理解,构建工具能实现的功能:

1. 代码转换: 从typescript->JavaScript,sass->css等;

2.  代码优化: 压缩HTML、css代码等;

3. 代码分割: 将通用的代码从多个文件中抽取出来;大文件切割成小文件;

4. 模块合并: 模块化项目里会有很多模块,比如一个模块引用了另一个模块这样子。构建工具可以将多个模块合并成一个模块;

5. 自动刷新: 监听代码的变化,对代码进行实时刷新;

6. 在代码提交到代码仓库之前进行代码校验,看是否符合规范或者单元测试是否通过;

7. 自动发布: 代码更新完毕之后,自动构建发布代码并传输给发布系统进行发布。

二、webpack是什么

关于webpack的作用,官网的一个图其实就说明了一切。


webpack是一个打包模块化JavaScript的工具。在webpack里一切文件皆模块。这样的好处是可以清楚的了解各模块之间的依赖关系,以便webpack进行组合与打包。打包的过程中:通过loader将webpack不能处理的文件转换成它能处理的文件,然后再通过plugins进行功能的扩展,比如压缩文件、分割文件的处理等,然后进行打包。

三、webpack的优缺点

优点:

1. 专注于模块化项目;

2. plugins能做的事情非常多;

3. 社区活跃。 

缺点: 

1、官方文档非常难懂,不利于学习;

2. plugins繁多,需要不断的学习才能灵活掌握;

3. 对初学者不利,调试很难定位问题。。

四、webpack核心概念

mode: 模式。在webpack4新引入的。可以配置成production、development两种值,而单元测试也属于开发模式下的。

entry: 入口。webpack执行的构建的第一步。

entry: {    
    // 入口 (多个文件作为一个入口 全局使用babel-polyfill  polyfill将会被打包进这个入口文件中, 而且是放在文件最开始的地方)    
    app: ['babel-polyfill', './src/main.js']
}复制代码

上面的例子是单页面项目配置的入口,只有一个入口文件,而babel-polyfill是一个转换js标准的工具,再加上.babelrc里的配置,就可以实现js标准处理

module: webapck中一切皆模块,webapck会从entry开始递归找到所有的依赖。在module.rules里进行loader的配置

module: {
    rules: [{        
        test: /\.js$/,        
        loader: 'babel-loader', // js处理        
        include: [ // Rule.include 是 Rule.resource.include 的简写。如果你提供了 Rule.include 选项,就不能再提供 Rule.resource          
            resolve('src'),          
            resolve('test'),          
            resolve('node_modules/webpack-dev-server/client')        
        ]      
    },
      ...    
    ]
}复制代码

devtool:  用哪一种sourceMap来处理。sourceMap的概念,简单理解,就是我们写的代码,在经过构建工具的处理后,如果在调试的时候出现什么错误,由于代码已经进行过了处理,若果不在处理前就标记好代码的各种信息,处理后无法定位问题,而sourceMap就是做标记的工作。比如说标记代码的行信息,列信息等等。用不同的模式下的souceMap,得到的代码信息不太一样。

devtool: config.build.productionSourceMap ? config.build.devtool : false,复制代码

resolve: 模块解析的相关配置。比如文件查找的优先级等

resolve: {    
    // 模块解析相关的配置    
    extensions: ['.js', '.vue', '.json'], // 这里的顺序代表匹配后缀的优先级,例如对于 index.js 和 index.jsx,会优先选择 index.js    
    alias: { // 如果我们有某个模块及其常用,经常编写相对路径很麻烦,就可以在此处配置某个模块的别名      
        '@': resolve('src')    
    }  
},复制代码

performance:  性能配置,里面的配置项能控制webpack如何通知资源和入口超过指定文件限制。

performance: {
    hints: 'warning', // 警告 室还有一个值是error
    maxAssetSize: 30000000, // 整数类型(以字节为单位) 资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积,控制 webpack 何时生成性能提示。默认250000    maxEntrypointSize: 50000000 // 整数类型(以字节为单位) 默认250000 此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示
}复制代码

plugins: 配置插件

plugins: [
    new minCssExtractPlugin({ // 该插件用于将css提取到单独的文件,以便多个页面共享一个css文件
        filename: utils.assetsPath('css/[name].[contenthash:8].css'),
        chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
    })
]复制代码

optimization: 优化打包的配置

optimization: { // 优化    
    splitChunks: { // 动态导入模块,webpack4+的全新通用分块策略配置    
        chunks: 'all',    
        cacheGroups: {      
            libs: {        
                name: 'chunk-libs',        
                test: /[\\/]node_modules[\\/]/,        
                priority: 10,        
                chunks: 'initial' // 只打包初始时依赖的第三方      
            },      
            elementUI: {          
                name: 'chunk-elementUI', // 单独将 elementUI 拆包          
                priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app          
                test: /[\\/]node_modules[\\/]element-ui[\\/]/        
            }      
        }    
    },    
    runtimeChunk: 'single', // 值 "single" 会创建一个在所有生成 chunk 之间共享的运行时文件    
    minimizer: [ //允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。      
        new UglifyJsPlugin({        
            uglifyOptions: {          
                mangle: { // 混淆            
                    safari10: true          
                }        
            },        
            sourceMap: config.build.productionSourceMap, // 编译后代码对源码的映射,用于网页调试        
            cache: true,        
            parallel: true      
        }),      
        // 压缩提取的CSS。使用此插件减少来自不同组件的可能重复的CSS      
        new OptimizeCSSAssetsPlugin()    
    ]  
}复制代码

output: 经过一系列处理,得到想要的结果。

output: {    
    path: config.build.assetsRoot,    
    filename: utils.assetsPath('js/[name].[chunkhash:8].js'),    
    chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
},复制代码

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


你可能感兴趣的:(webpack的个人理解(一))