ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【专项学习】 —— Webpack5从入门到精通课程学习(五)

2022-03-08 11:35:20  阅读:186  来源: 互联网

标签:文件 Webpack5 入门 js 学习 html test loader css


这篇主要介绍《webpack优化环境配置(中)》。

知识点包括:

  1. 第一种方法
  2. 第二种方法
  3. 第三种方法

 

一、tree shaking

1、复制上一篇的生产环境缓存工程文件。然后重命名。

tree shaking(树摇)去除无用的代码

2、在src文件夹下新建test.js,测试使用该功能,是否会把没有引用的js代码也打包。

test.js代码如下,两个函数都使用export暴露出去。

export function mul(x, y) {
    return x * y;
}
export function count(x, y) {
    return x - y;
}

3、index.js代码,我们只引入test.js中的一个mul函数,那么count函数就没有被用到,那么使用tree shaking后,打包后的文件应该没有count函数,被去掉了。

import '../css/index.css';
// 引入icon-font样式文件
import '../iconfit/iconfont.css';

// 只引入test.js中的一个mul函数
import { mul } from './test';

function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}


console.log(mul(2, 2));

console.log(sum(1, 2, 3, 4));

4、config中需要修改运行环境为production环境,注释说明入代码中所写

const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');

// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'production'

// tree shaking:去除无用代码
//前提: 1.必须使用ES6模块化2.开启production环境
//作用:减少代码体积
//在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
//问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
//,所以需要配置为"sideEffects" : ["*.css"]

module.exports = {
    entry: {
        // 把之前的单入口修改为多入口
        // 有几个入口,打包就生成几个built.js
        index: './src/js/index.js',
        test: './src/js/test.js'
    },
    output: {
        // [name]:取entry中的入口文件名进行命名
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
            // oneOf 是每一个文件,只匹配到一个loader即可,
            // 不像之前,每个文件都要把下列loader全部匹配一遍
            // 注意不能有两个loader处理同一个类型文件
            oneOf: [
                {
                    // 检测css文件,并打包
                    test: /\.css$/,
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 对css做兼容性处理
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        }
                    ]
                },
                {
                    // 检测less文件,并打包
                    test: /\.less$/,
                    // use内代码,是从下往上的顺序执行的
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        },
                        'less-loader'
                    ]
                },
                {
                    // js兼容性处理
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                                '@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs:
                                    {
                                        version: 3
                                    },
                                    targets: {
                                        // 浏览器兼容的版本
                                        chrome: '60',
                                        firefox: '50'
                                    }
                                }
                            ]
                        ]
                    }
    
                },
                {
                    //对图片进行打包处理
                    test: /\.(jpg|png|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 8 * 1024,
                        outputPath: 'imgs',
                        esModule: false
                    },
                    type: 'javascript/auto'
                },
                {
                    // 处理html中的图片文件
                    test: /\.html$/,
                    loader: 'html-loader',
                    options: {
                        esModule: false,
                    }
    
                },
                {
                    // 处理其他文件,如字体图标等
                    exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                    loader: 'file-loader',
                    options: {
                        outputPath: 'media',
                        esModule: false,
                    },
                    type: 'javascript/auto'
                }
            ]
        }]    
    },
    plugins: [
        new minicssextractplugin({
            // 打包提取成单独文件
            filename: 'css/built.[contenthash:10].css'
        }),
        new cssminimizerwebpackplugin(
            // 压缩css文件
        ),
        new Htmlwebpackplugin({
            template: './src/index.html',
            // 压缩html
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        })
    ],
    // 生产环境下,js自动压缩
    mode: 'production'
}

5、package.json中代码

{
  "name": "webpack_production",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.16.5",
    "@babel/preset-env": "^7.16.5",
    "babel-loader": "^8.2.3",
    "core-js": "^3.21.1",
    "css-loader": "^6.5.1",
    "css-minimizer-webpack-plugin": "^3.3.1",
    "eslint": "^8.10.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-webpack-plugin": "^3.1.1",
    "file-loader": "^6.2.0",
    "html-loader": "^3.0.1",
    "html-webpack-plugin": "^5.5.0",
    "less-loader": "^10.2.0",
    "mini-css-extract-plugin": "^2.4.5",
    "postcss-loader": "^6.2.1",
    "postcss-preset-env": "^7.1.0",
    "style-loader": "^3.3.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "sideEffects": [
    "*.css"
  ]
}

注意:为了能够识别ES6模块,需要下载core-js包。输入npm i core-js -D,然后输入npm run build即可进行打包。

最后打包成功的built.js中只包含了引入并使用的mul函数,未被引入和使用的count函数并没有被打包进来。 

 

二、code split(代码分割)

第一种方法

代码分割会把打包的一个大文件分割成多个不同的文件,这样在加载的时候就会并行加载,速度更快。还可以实现按需下载。

1、复制上一小节工程文件,并重命名。

在src下的js文件夹中有两个.js文件,我们以往打包是最后只生成了一个built.js文件,如果想生成两个呢。

2、首先修改index.js代码,去除引入的test.js代码

import '../css/index.css';
// 引入icon-font样式文件
import '../iconfit/iconfont.css';


function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}

console.log(sum(1, 2, 3, 4));

2、修改webpck.config.js代码

const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');

// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'production'

// tree shaking:去除无用代码
//前提: 1.必须使用ES6模块化2.开启production环境
//作用:减少代码体积
//在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
//问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
//,所以需要配置为"sideEffects" : ["*.css"]

module.exports = {
    entry: {
        // 把之前的单入口修改为多入口
        // 有几个入口,打包就生成几个built.js
        index: './src/js/index.js',
        test: './src/js/test.js'
    },
    output: {
        // [name]:取entry中的入口文件名进行命名
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
            // oneOf 是每一个文件,只匹配到一个loader即可,
            // 不像之前,每个文件都要把下列loader全部匹配一遍
            // 注意不能有两个loader处理同一个类型文件
            oneOf: [
                {
                    // 检测css文件,并打包
                    test: /\.css$/,
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 对css做兼容性处理
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        }
                    ]
                },
                {
                    // 检测less文件,并打包
                    test: /\.less$/,
                    // use内代码,是从下往上的顺序执行的
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        },
                        'less-loader'
                    ]
                },
                {
                    // js兼容性处理
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                                '@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs:
                                    {
                                        version: 3
                                    },
                                    targets: {
                                        // 浏览器兼容的版本
                                        chrome: '60',
                                        firefox: '50'
                                    }
                                }
                            ]
                        ]
                    }
    
                },
                {
                    //对图片进行打包处理
                    test: /\.(jpg|png|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 8 * 1024,
                        outputPath: 'imgs',
                        esModule: false
                    },
                    type: 'javascript/auto'
                },
                {
                    // 处理html中的图片文件
                    test: /\.html$/,
                    loader: 'html-loader',
                    options: {
                        esModule: false,
                    }
    
                },
                {
                    // 处理其他文件,如字体图标等
                    exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                    loader: 'file-loader',
                    options: {
                        outputPath: 'media',
                        esModule: false,
                    },
                    type: 'javascript/auto'
                }
            ]
        }]    
    },
    plugins: [
        new minicssextractplugin({
            // 打包提取成单独文件
            filename: 'css/built.[contenthash:10].css'
        }),
        new cssminimizerwebpackplugin(
            // 压缩css文件
        ),
        new Htmlwebpackplugin({
            template: './src/index.html',
            // 压缩html
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        })
    ],
    // 生产环境下,js自动压缩
    mode: 'production'
}

最后打包生成的文件,这就是对js文件进行了代码分割,通过修改入口文件的方法。  

 

第二种方法

1、我们将config.js代码的入口文件改回一个,并使用一个内置的配置splitChunks开启代码分割功能。

const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');

// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'production'

// tree shaking:去除无用代码
//前提: 1.必须使用ES6模块化2.开启production环境
//作用:减少代码体积
//在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
//问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
//,所以需要配置为"sideEffects" : ["*.css"]

module.exports = {
    entry: './src/js/index.js',
    output: {
        // [name]:取entry中的入口文件名进行命名
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
            // oneOf 是每一个文件,只匹配到一个loader即可,
            // 不像之前,每个文件都要把下列loader全部匹配一遍
            // 注意不能有两个loader处理同一个类型文件
            oneOf: [
                {
                    // 检测css文件,并打包
                    test: /\.css$/,
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 对css做兼容性处理
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        }
                    ]
                },
                {
                    // 检测less文件,并打包
                    test: /\.less$/,
                    // use内代码,是从下往上的顺序执行的
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        },
                        'less-loader'
                    ]
                },
                {
                    // js兼容性处理
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                                '@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs:
                                    {
                                        version: 3
                                    },
                                    targets: {
                                        // 浏览器兼容的版本
                                        chrome: '60',
                                        firefox: '50'
                                    }
                                }
                            ]
                        ]
                    }
    
                },
                {
                    //对图片进行打包处理
                    test: /\.(jpg|png|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 8 * 1024,
                        outputPath: 'imgs',
                        esModule: false
                    },
                    type: 'javascript/auto'
                },
                {
                    // 处理html中的图片文件
                    test: /\.html$/,
                    loader: 'html-loader',
                    options: {
                        esModule: false,
                    }
    
                },
                {
                    // 处理其他文件,如字体图标等
                    exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                    loader: 'file-loader',
                    options: {
                        outputPath: 'media',
                        esModule: false,
                    },
                    type: 'javascript/auto'
                }
            ]
        }]    
    },
    plugins: [
        new minicssextractplugin({
            // 打包提取成单独文件
            filename: 'css/built.[contenthash:10].css'
        }),
        new cssminimizerwebpackplugin(
            // 压缩css文件
        ),
        new Htmlwebpackplugin({
            template: './src/index.html',
            // 压缩html
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        })
    ],
    // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
    // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    },
    // 生产环境下,js自动压缩
    mode: 'production'
}

2、然后修改index.js代码,增加一个官方的node_modules(jquery)。

import '../css/index.css';
// 引入icon-font样式文件
import '../iconfit/iconfont.css';
// 引入jquery
import $ from 'jquery';


function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}

console.log($);

console.log(sum(1, 2, 3, 4));

3、然后安装jquery,npm i jquery --save,最后打包npm run build

会将自己编写的index.js和jquery有关的js分开生成,即生成两个.js文件。

 

第三种方法

第三种方法是通过修改index.js文件实现的,import动态导入语法,能将某个文件单独打包,config.js中入口还是修改为单入口

我们希望除了官方的node_modules,其他使用的js文件也可以被分割打包出来

1、首先把config.js中的第二种方法使用的插件去掉。

const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');

// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'production'

// tree shaking:去除无用代码
//前提: 1.必须使用ES6模块化2.开启production环境
//作用:减少代码体积
//在package.json中配置"sideEffects" : false所有代码都没有副作用(都可以进行tree shaking)
//问题:可能会把css/@babel/polyfill (副作用)文件干掉,因为这些文件都是引入了,但没有直接使用
//,所以需要配置为"sideEffects" : ["*.css"]

module.exports = {
    entry: './src/js/index.js',
    output: {
        // [name]:取entry中的入口文件名进行命名
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
            // oneOf 是每一个文件,只匹配到一个loader即可,
            // 不像之前,每个文件都要把下列loader全部匹配一遍
            // 注意不能有两个loader处理同一个类型文件
            oneOf: [
                {
                    // 检测css文件,并打包
                    test: /\.css$/,
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 对css做兼容性处理
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        }
                    ]
                },
                {
                    // 检测less文件,并打包
                    test: /\.less$/,
                    // use内代码,是从下往上的顺序执行的
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        },
                        'less-loader'
                    ]
                },
                {
                    // js兼容性处理
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                                '@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs:
                                    {
                                        version: 3
                                    },
                                    targets: {
                                        // 浏览器兼容的版本
                                        chrome: '60',
                                        firefox: '50'
                                    }
                                }
                            ]
                        ]
                    }
    
                },
                {
                    //对图片进行打包处理
                    test: /\.(jpg|png|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 8 * 1024,
                        outputPath: 'imgs',
                        esModule: false
                    },
                    type: 'javascript/auto'
                },
                {
                    // 处理html中的图片文件
                    test: /\.html$/,
                    loader: 'html-loader',
                    options: {
                        esModule: false,
                    }
    
                },
                {
                    // 处理其他文件,如字体图标等
                    exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                    loader: 'file-loader',
                    options: {
                        outputPath: 'media',
                        esModule: false,
                    },
                    type: 'javascript/auto'
                }
            ]
        }]    
    },
    plugins: [
        new minicssextractplugin({
            // 打包提取成单独文件
            filename: 'css/built.[contenthash:10].css'
        }),
        new cssminimizerwebpackplugin(
            // 压缩css文件
        ),
        new Htmlwebpackplugin({
            template: './src/index.html',
            // 压缩html
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        })
    ],
    // 代码分割的配置,可以将node_modules中代码单独打包一个chunk输出
    // 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk输出
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    },
    // 生产环境下,js自动压缩
    mode: 'production'
}

2、修改index.js代码,import动态导入语法,能将某个文件单独打包

import '../css/index.css';
// 引入icon-font样式文件
import '../iconfit/iconfont.css';


function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}

console.log(sum(1, 2, 3, 4));

// 通过js代码,实现代码分割功能。以ES10的方法引入test.js
// import动态导入语法,能将某个文件单独打包
// webpackChunkName:'test'表示打包后的文件名为test
import(/*webpackChunkName:'test'*/'../js/test')
  .then((result) => {
    console.log(result);
  })
  .catch(() => {
    console.log('文件加载失败~');
  })

3、输入npm run build打包


注:笔记转载自疯子的梦想@博客,课程来自尚硅谷b站Webpack5实战课程

标签:文件,Webpack5,入门,js,学习,html,test,loader,css
来源: https://www.cnblogs.com/ljq66/p/15979657.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有