学习webpack的基本配置和splitChunks配置

entry 入口配置

entry表示入口,一般是一个字符串,表示入口文件的路径。如果是多入口就需要将entry拥有很多键值对的对象,属性名就是每个入口的名字,值是每个入口的路径。

// 单入口
entry: './src/main.js'
// 多入口
entry: {
    
    
    main: './src/main.js',
    other: './src/other.js'
}

output 出口配置

output出口的配置一般配置产出文件的名字和路径。如果入口配置是多入口,那出口文件也肯定是一一对应的。

const path = require('path')

output: {
    
    
    filename: '[name].js' // [name]表示生成文件名字与入口设置的名字相同
    path: path.resolve(__dirname, 'dist')// 表示最后输出的目录是当前项目的dist目录下,__dirname是一个在node.js下面的一个表示当前项目路径的常量
}

配置好了entry和output之后。如果你的项目只有js文件,那么,它已经可以正常运行了。通过运行webpack命令

// --progress 显示打包进度百分比
// --stats=varbose 显示打包全日志,还有其它属性值,normal默认日志显示设置,只显示部分主要日志。errors-info只在报错时显示错误日志
npx webpack --stats=varbose --progress

假设你项目入口是main.js文件。它引用了a.js和b.js两个文件。在运行上面的命令之后,在项目的dist文件生成了一个新的main.js文件。这个文件就是打包之后的产物。

我们知道了webpack的第一个作用:打包。打包各种类型的文件。

上面我们只有js文件,未免太简单了些。其实webpack可以还可以打包CSS,图片,Vue等各种类型的文件

处理vue文件

下面我们添加处理vue文件的打包方式。处理vue类型的文件,需要专门的vue-loader,配置到规则里面。

module: {
    
    
    rules: [
        {
    
    
            // 处理.vue后缀的文件
            test: /\.vue$/,
            use: 'vue-loader'
        },
    ]
}

这样就可以了吗?答案是还不够。还需要在插件里面添加一个对应的VueLoaderPlugin插件。

const {
    
     VueLoaderPlugin } = require('vue-loader')
module: {
    
    
    rules: [
        {
    
    
            // 处理.vue后缀的文件
            test: /\.vue$/,
            use: 'vue-loader'
        },
    ]
},
plugins: [
    new VueLoaderPlugin() // ???
]

这样才可以完整的处理vue类型的文件。它其它是将.vue文件变成了三个不同类型文件,其中的script和templte都会被处理成js,style标签的部分则会由vue-style-loader去处理。

处理CSS文件

其中 vue-style-loader 是对.vue文件里面css部分进行处理,对所有样式添加scoped字段,使之只在组件div下生效。不进行这层的处理,样式就全部都成了全局样式。

module: {
    
    
    rule: [
        {
    
    
            // 处理css文件
            test: /\.css$/,
            use: [
                'vue-style-loader',
                'css-loader'
            ]
        }
    ]
}

css-loader和style-loader的区别:css-loader 会把css文件打包成commonjs模块。style-loader 则是主要把js里面的样式资源插入到html的style标签里面,让样式生效。

处理图片

module: {
    
    
    rule: [
        {
    
    
            test: /\.(png|svg|jpe?g|gif)$/,
            use: {
    
    
                loader: 'file-loader',
                options: {
    
    
                    name:'assets/[name].[ext]',
                }
            }
        }
    ]
}

使用 file-loader 来处理各种后缀的图片,png,svg,jpg,gif格式的图片。这个加载器的主要作用是解决开发和打包时,图片路径不一致,导致的图片不能访问的问题。也就是解决路径问题

还有一个loader是 url-loader,这两个加载器的区别是:url-loader 主要作用是为了减少http请求。会将图片编码成dataURI(base64等)打包到文件里面,这样直接访问dataURI就可以显示图片了,也就不用再请求了。

当然也不能全部图片都进行编码,大尺寸的图片编码非常消耗性能,还是应该使用http请求。所以 url-loader 里面有一个参数limit用来限制可以进行编码的图片大小,小于这个尺寸的会将图片进行编码,而超过这个尺寸的图片还是会使用 file-loader 进行处理。也就是说 url-loader 其实是包含有 file-loader 的。

// url-loader的使用方法
module: {
    
    
    rule: [
        {
    
    
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
    
    
                limit: 10000, // 单位是:B(字节)
            }
        }
    ]
}

配置文件压缩

目前我们打包好的文件,直接开始就可以看到源码,基本就是webpakc把不同文件使用胶水代码合并在了一起。

所以不能直接使用在生产环境中,需要将代码压缩,使其基本不可读。保护代码的安全

而且压缩代码,文件的体积也会变小,有利于网络传输

optimization: {
    
    
    minimize: true // 开启默认压缩配置
    minimizer: [ // 自定义压缩配置(如果需要的话)
        new TerserPlugin({
    
    
            ......
        })
    ]
}

具体配置用到的时候再说。

公共库代码分离

optimization: {
    
     // 这个配置项是对打包流程进行优化的配置
        splitChunks: {
    
     // 
            cacheGroups: {
    
     //
                // 外部也可以进行配置,当内部配置不与外部配置冲突的时候,使用内部内部配置,不冲突时,共用。
                commons: {
    
    
                    test: /[\\/]node_modules[\\/]/, // 配置是一个正则,所以引入来自node_modules文件夹里面的文件,都会打包成一个vendors.js文件
                    name: "vendors", // 打包之后,文件的名字
                    chunks: "initial" // 不同导入方式进行配置

                }
            }
        }
    }

参数chunks

参数chunks有三个值,分别是initial:对异步或者同步导入的模块分别进行打包,打包到不同的文件里面。async:不配置时的默认值,只会将异步导入的模块进行单独打包。all:无论异步还是同步加载的模块,都会单独进行打包,并且最后都会打包到同一个文件里面去。

chunks的参数提到了异步和同步导入模块。那么怎么算是同步导入,怎么又算是异步导入呢?

  • 同步写法:import 'xxx' 或者 require('xxx')
  • 异步写法:import('xxx') 或者 require('xxx', () => { yyy })

而我们常用的 import xxx from 'path' 这种写法也是同步导入的。

参考MDN上说的,只有 import('xxx') 这种像是函数一样的调用是异步导入模块的,其它都是同步的。而且 import('xxx') 会返回一个Promise对象去操作异步返回的模块对象。

import('XXX')
    .then(module => {
    
     // 像这样去操作异步返回的模块
        ......
    })
    .catch(error => {
    
    
        ......
    })

这种import异步导入模块的常见用法是在routes.js路由里面。

{
    
    
    path: '',
    component: () => import('XXX'), // 异步加载路由
    children: [
        ......
    ]
}

同步导入写法 import 'xxx' 它的作用是运行模块(而不是导入模块)。使用模块的副作用。比如使用这样方法导入CSS,运行模块会进行样式的添加,本身就是一种副作用。而不是希望得到CSS文件里面暴露的模块(这也是不可能的)。

猜你喜欢

转载自blog.csdn.net/cuipp0509/article/details/118302944