01webpack介绍、基础详细配置

webpack介绍、基础配置

webpack介绍

webpack流程
Webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)

  • webpack可以做的事情
    代码转换、文件优化、代码分割、模块合并、自动刷新、代码校验、自动发布

webpack安装

  • 安装本地的webpack
  • webpack webpack-cli -D(-D是指开发依赖,表示上线不需要这个包)

例如:这里用的是yarn管理工具

  1. 初始化:yarn init -y
  2. 安装webpack-cli:yarn add webpack webpack-cli -D

webpack可以进行0配置

  • 打包工具 -> 输出后的结果(js模块)
  • 打包(支持我们的js的模块化)
  • 打包命令:npx webpack(webpack5.0以上支持)
    执行原理:这样执行会去找node_modules下的bin文件夹,bin中有webpack.cmd文件,然后就执行webpack/webpack.js文件,然后需要安装webpack-cli
    webpack.cmd
@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\..\webpack\bin\webpack.js" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node  "%~dp0\..\webpack\bin\webpack.js" %*
)

手动配置webpack

  • 默认配置文件的名字 webpack.config.js
  • 为什么叫webpack.config.js这个名字?
    因为node_moudes下的webpack下会默认调用webpack-cli,webpack-cli里面有解析module.exports对象中的参数,在config-yargs.js里,这里面有解析的关系和说明,你可以搜索关键字webpack.config.js来查找。

Webpack 五个核心概念

  1. Entry:入口
  2. Output:输出
  3. Loader:让Webpack能够去处理那些非JavaScript文件
  4. Plugins:插件
  5. Mode:Webpack使用相应模式的配置

webpack.config.js

//webpack 是node写出来的,用node的写法
let path = require('path');

//console.log(path.resolve('dist'));
module.exports = {
	// node配置
    mode: 'development',//模式,默认有两种production / development
	// entry 入口配置
    entry: './src/index.js',//入口
	// output 输出配置
    output: {
        filename: 'bundle.js',//打包后的文件名
		// __dirname nodejs的变量,代表当前文件的目录绝对路径
        path: path.resolve(__dirname,'dist')//路径必须是一个绝对路径
    },
    module: {
	rules: [
		// 详细loader配置
	]
    },
    // plugins 插件配置
    pugins:[
      // 详细plugins的配置
    ]
}

entry配置

/**
 * entry: 入口起点
 *  1. string --> './src/index.js'
 *      单入口
 *      打包形成一个chunk,输出一个bundle文件。
 *  2. array --> ['./src/index.js', './src/add.js']
 *      多入口
 *      所有入口文件最终只会形成一个chunk,输出去只有一个bundle文件
 *          --> 只有在HMR功能中让html热更新生效~
 *  3. object
 *      多入口
 *      有几个入口问价就形成几个chunk,输出几个bundle文件
 *      此时chunk的名称是key
 *      entry: {
            index: './src/index.js',
            add: './src/add.js'
        }

        --> 特殊用法
        entry: {
            index: ['./src/index.js', './src/count.js'],
            add: './src/add.js'
        }
 */

output配置

output: {
     // 文件名称(指定名称 + 目录)
     filename: 'js/[name].[contenthash:10].js',
     // 输出文件目录(将来所有资源输出的公共目录)
     path: resolve(__dirname, 'build'),
     // 所有资源引入公共路径前缀 --> 'imgs/a.jpg' --> 'imgs/a.jpg'
     publicPath: '/',
     chunkFilename: 'js/[name].[contenthash:10]_chunk.js' // 非入口chunk的名称
     // library: '[name]', // 整个库向外暴露的变量名  一般不用
     // libraryTarget: 'window', // 变量名添加到哪个上 browser
     // libraryTarget: 'global', // 变量名添加到哪个上 node
     // libraryTarget: 'commonjs' 
 },

module配置

module: {
    // loader的配置
    rules: [
        {
            // 处理css资源
            test: /\.css$/,
            // 多个loader用use
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
            ]
        },
        {
            // 可以处理less文件,还有sass stylus  node-sass sass-loader
            // stylus stylus-loader
            test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader', // 把less -> css  先解析less再执行css
                'less-loader' // 把less -> css  先解析less再执行css
            ]
        },
        {
            // 处理图片资源
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
                limit: 8 * 1024,
                name: '[hash:10].[ext]',
                // 关闭es6模块化
                esModule: false,
                outputPath: 'imgs'
            }
        },
        {
            // 处理html中img资源
            test: /\.html$/,
            loader: 'html-loader'
        },
        {
            // 处理其他资源
            exclude: /\.(html|js|css|less|jpg|png|gif)/,
            loader: 'file-loader',
            options: {
                name: '[hash:10].[ext]',
                outputPath: 'media'
            }
        },
        {
            /**
             * 语法检查:eslint-loader eslint
             *     注意:只检查自己写的源代码,第三方的库是不用检查的
             *     设置检查规则:
             *      package.json中eslintConfig中设置~
             *      "eslintConfig": {
                        "extends": "airbnb-base"
                    }
             *      airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint
             */
            test: /\.js$/,
            // 排除node_modules下的js文件
            exclude: /node_modules/,
            // 只检查src下的js文件
            include: resolve(__dirname, 'src'),
            // 优先执行
            enforce: 'pre',
            // 延后执行
            // enforce: 'post',
            // 单个loader用loader
            loader: 'eslint-loader',
            options: {
                // 自动修复eslint的错误
                fix: true
            }
        },
        {
            // 以下配置只会生效一个
            oneOf: []
        }
    ]
},

resolve配置

resolve: {
    // 配置解析模块路径别名:优点简写路径;缺点路径没有提示
    alias: {
        $css: resolve(__dirname, 'src/css')
    },
    // 配置省略文件路径的后缀名
    extensions: ['.js', '.json', '.jsx', '.css'],
    // 告诉webpack解析模块是去找哪个目录
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
}

optimization配置

  • 引入插件terser-webpack-plugin
    npm install terser-webpack-plugin -D
  • 在webpack.config.js中配置插件
    const TerserWebpackPlugin = require('terser-webpack-plugin')
optimization: {
    splitChunks: {
        chunks: 'all',
        /*// 默认值,可以不写~
        minSize: 30 * 1024, // 分割的chunk最小为30kb
        maxSiza: 0, // 最大没有限制
        minChunks: 1, // 要提取的chunk最少被引用1次
        maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量
        maxInitialRequests: 3, // 入口js文件最大并行请求数量
        automaticNameDelimiter: '~', // 名称链接符
        name: true, // 可以使用命名规则
        cacheGroups: { // 分割chunk的组
            // node_modules文件会被打包到vendors组的chunk中。 --> vendors ~xxx.js
            // 满足上面的公共规则,如:大小超过30kb,至少被引用一次
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10
            },
            default: {
                // 要提取的chunk最少被引用2次
                minChunks: 2,
                // 优先级
                priority: -20,
                // 如果当前要打包的模块,和之前被提取的模块是同一个,就会复用,而不是重新打包
                reuseExistingChunk: true
            }
        }*/
    },
    // 将当前模块的记录其他模块的hash单独打包为一个文件runtime
    // 解决:修改a文件导致b文件的contenthash变化
    runtimeChunk: {
        name: entrypoint => `runtime-${entrypoint.name}`
    },
    TerserWebpackPlugin: [
        // 配置生产环境的压缩方案:js和css
        new TerserWebpackPlugin({
            // 开始缓存
            cache: true,
            // 开始多进程打包
            parallel: true,
            // 启动source-map
            sourceMap: true
        })
    ]
}

posted on 2020-07-01 21:29  铃之森  阅读(194)  评论(0)    收藏  举报

导航