webpack 5项目编译和打包js文件

1,520 阅读3分钟

今天继续填webpack坑啦。继上次讲了webpack5编译和处理css文件后,今天聊一聊webpack5是如何处理js文件的。

目标

  • 编译ES6
  • 引入eslint
  • 压缩js文件
  • 引入全局变量

知识点脑图

image.png

项目中用到的代码

github.com/joychenke/w…

编译ES6

编译ES6语法是通过babel实现的。

  • 安装babel  yarn add  babel-loader @babel/core @babel/preset-env -D

    • @babel/core 是使用Babel进行转码的核心npm包,使用的babel-cli,babel-node都依赖这个包

    • @babel/preset-env 是babel预制套件,包含各种可能用到的转译工具

  • 在webpack.config.js的 module,rules中加入babel配置。注意加includes,仅处理src文件夹中的js文件

{
                test: /\.js$/, //匹配js文件
                use: ['babel-loader'],
                include: path.resolve(__dirname, 'src')
}
  • 新增一个.babelrc文件,配置babel
{
    "presets": [
        "@babel/preset-env"
    ],
    "plugins": []
}
  • 用了以上配置后,发现还是不能用async await 。网上找了以下,需要安装 @babel/plugin-transform-runtime 才可以
  • 安装@babel/plugin-transform-runtime  ,yarn add @babel/runtime @babel/plugin-transform-runtime 
  • 修改.babelrc文件,配置transform-runtime。此时async await就可以使用了。
{
    "presets": [
        "@babel/preset-env"
    ],
    "plugins": [
        "@babel/plugin-transform-runtime"
    ]
}

(网上说 @babel/runtime 是运行环境中所需要的依赖包,要安装在dependencies里;而 @babel/plugin-transform-runtime 是开发依赖,只用安装在 devDependencies里,试了下,并不是网上说的这样,都安装在devDependencies里也是可以的 )

添加eslint-loader 格式化代码

  • 安装 eslint 和 eslint-loader   yarn add eslint eslint-loader -D
  • 在  webpack.config.js  中配置 babel-loader
{
                test: /\.js$/, //匹配js文件
                use: ['babel-loader',
                    {
                       loader: 'eslint-loader',
                        options: {
                          enforce: 'pre'  // 前置loader,webpack会优先处理
                        }
                    }
                ],
                include: path.resolve(__dirname, 'src')
            },
  • 在根目录下新增 .eslintrc.json。文件来源于官网demo下载的文件 cn.eslint.org/demo/
  • 做完以上步骤后,会发现,项目报错了,3个问题
//问题1
module没有定义

//问题2
const是保留字

// 问题3
ESLint Parsing error: Unexpected token
  • 问题1和2的解决方法是,配置eslint,使其支持es6和node语法。问题3是引入 babel-eslint。先安装 babel-eslint, 然后修改 .eslintrc.json
//  安装babel-eslint
yarn add babel-eslint -D

// 修改 .babelrc.json
{
   ...         // 其他配置项
   "env": {
     "es6": true,
     "node": true
    },
    "parser": "babel-eslint"
}
  • 重启服务 npm run dev, eslint 就配置好了

压缩js文件

  • terser-webpack-plugin 是用来压缩js的plugin
  • 配置此插件
const TerserWebpackPlugin = require('terser-webpack-plugin')

optimization: {
    minimizer: [
        new OptimizeCssAssetsWebpackPlugin(),
        new TerserWebpackPlugin()
   ]
}
  • 重新打包 npm run build。可以对比压缩之前和压缩之后的js文件,明显变小。

引入全局变量

有些插件是很多组件都需要使用的,例如jquery,引入一个全局属性$指向jquery对象,对我们非常方便且必要。引入全局对象有两种方法,1.ProvidePlugin 2.expose-loader。下面就分别讲一下,如何用这两种方式注入全局变量。

  1. 全局注册jQuery
  • 全局安装jQuery,yarn add jquery
  • 使用webpack模块提供的ProvidePlugin插件,引入全局属性 $,指向jquery对象
// 引入 webpack 模块
const Webpack = require('webpack')


// 在webpack.config.js的plugins中加入下面代码        
new Webpack.ProvidePlugin({
    $: 'jquery'  // 将jQuery加到全局变量中
})
  • 重新启动服务,会发现有个报错  '$' is not defined  no-undef
  • 这个报错是eslint报出来的。找了下原因,是因为全局变量jquery或者$需要先声明下。修改 .eslintrc.json。然后重启服务。(修改了.eslintrc.json后,需要手动重启才能生效)
//  亲测下面两种方式都有效

// 在env中添加jquery: true    
"env": {
        "es6": true,
        "node": true,
        "jquery": true
    },

// 或者添加 和 env 平级的 globals 属性
    "globals": {
        "$": true
    },
  1. 以上讲的是通过webpack.ProvidePlugin 来注入全局变量,还可以通过expose-loader添加全局变量。在开始演示之前,先解决index.js中如何兼容import 和 require的问题。还是修改下 .eslintrc.json,然后重启服务
{
        ... // 其他属性
    "parserOptions": {
        "ecmaVersion": 2020,
        "sourceType": "module",
        ... // 其他属性
    },
    ... // 其他属性
}

下面以dayjs为例来说明,如何使用expose-loader 来引入全局变量,安装dayjs yarn add day.js,先说下内联方式的用法。

  • expose-loader是内联loader,既可以用内联的方式使用,也可以用webpack.config.js中配置的方式使用。先说下内联使用
1. 在info.js文件中写上以下代码。意思是将 `$day` 添加到全局对象中,其名称为 $day
import $day from "expose-loader?exposes=$day!dayjs"

2. 在需要使用day.js的文件中,直接使用 $day 即可
const time = $day().format('YYYY-MM-DD')
console.log(time)
  • 做好以上配置后,重启服务,会发现报错 '$day is not defined  no-undef。 eslint报错了,需要在eslint中再加个配置,声名以下全局属性$day
"globals": {
    "$day": true
},
  • expose-loader除了用在组件中,还可用在webpack.config.js中。使用方法可以参考官网 webpack.docschina.org/loaders/exp…,具体实现分为两步,1. webpack中配置 expose-loader  2. 在顶层的js中配置 import $day from "dayjs"
// step1:在webpack中配置 expose-loader           
 {
                // require.resolve 调用是一个 Node.js 函数,用于给出模块的绝对路径
                test: require.resolve('dayjs'),  
                loader: 'expose-loader',
                options: {
                    exposes: ['$day']    
                }
            },

// step2: 在第一个执行的js文件里引入 dayjs
import $day from "dayjs"

结语

今天关于webpack5对js的处理就介绍到这里了,后面会继续更新webpack5编译和打包图片文件

image.png