前端自动化构建工具:Webpack(三)—— Webpack 生产环境的基本配置

三 webpack 生产环境的基本配置

上一篇文章我们讲完了 webpack 开发环境的配置,接下来就该讲 webpack 生产环境的配置了。前面已经说到,开发环境是启用代码本地调试运行的环境,帮助我们更高效率的开发。而生产环境则需要启动能让代码优化上线运行的环境,我们需要进行一系列的优化操作,以达到更好的用户体验。

3.1 将CSS抽离成单独的文件

之前我们处理 css 资源,最终都是使用 style-loader 在 js 文件中去动态创建 style 标签,再把样式写入 style 标签里。这样做有一个问题在于,会使打包后的 index.js 文件体积非常大,并且在读取 js 代码的过程中因为 js 单线程的原因造成样式渲染速度较慢,导致页面出现短暂的白屏闪烁。因此,我们需要替代之前将 css 写入 js 文件的做法,将 css 文件单独抽离出来,再通过 link 标签引入。同时为了减少网络请求的带宽浪费,我们需要将抽离出来的多个 css 文件合并为一个单独的 css 文件。实现这个功能,我们需要借助一个名为 mini-css-extract-plugin 的插件:

npm i mini-css-extract-plugin --save-dev

引入过后,我们首先要在 plugins 中对其进行实例化,然后在处理 css 资源的 loader 中用该插件的 loader 属性去替换原来的 style-loader:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 将 css 抽离成单独的文件

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 打包样式资源 
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader, // 替换原来的 style-loader
          'css-loader',
          'less-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader, // 替换原来的 style-loader
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin() // 实例化 mini-css-extract-plugin 插件
  ],
  mode: 'development'
}

我们在 src 目录下创建两个 css 文件并在 index.js 中引入,然后执行 webpack:

你会发现打包后的 dist 目录多了一个 main.css 文件,并将 a.css 和 b.css 文件的样式都包含进去,而不是像之前直接写入打包后的 built.js 文件了:

main.css 是默认命名,如果你想修改命名,可以在刚才实例化插件的地方传入对应的参数:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 将 css 抽离成单独的文件

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 打包样式资源 
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    })
  ],
  mode: 'development'
}

3.2 对CSS进行兼容性处理

css 里有很多样式在不同的浏览器里需要使用不同的写法,比如像弹性盒子 flex。但是,如果每次在写 css 的过程要自己去针对不同浏览器写不同的样式,那工作量将是难以想象的。好在已经有一些现成的工具,来帮助我们完成这些工作。对 css 进行兼容性处理,我们需要同时安装 postcss-loader 与 postcss-preset-env 插件(新版本的 postcss-loader 用法发生很大的变化,笔者暂时还没有弄懂,只能暂时用 3.0.0 版本了,以下过程基于该版本才能正常运行):

npm i postcss-loader@3.0.0 postcss-preset-env --save-dev

loader 的写法,除了用字符串的形式,还可以用对象的形式,如:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader' // 对象写法,等同于直接写 'css-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    })
  ],
  mode: 'development'
}

loader 直接写字符串的方式,会使用该 loader 默认的配置;而使用对象的形式,我们可以在 options 属性里进行一些自定义配置。对于 3.0.0 版本的 postcss-loader,我们必须使用对象的方式,配合 postcss-preset-env 插件(该插件提供预设的 css 兼容代码),才可以正常的运行:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 打包样式资源 
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
          {
            loader: 'postcss-loader', // 对 css 进行兼容性处理
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')() // 使用 postcss-preset-env 插件读取 node 环境变量
              ]
            }
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    })
  ],
  mode: 'development'
}

尝试运行这个文件,你会看到打包后的 css 文件,确实对某些样式做了兼容性处理,但对弹性盒子并没有做兼容性处理。原因在于该 loader 默认使用的是开发环境的环境变量,只兼容部分新版本浏览器,并未对所有版本浏览器进行兼容。对此,我们可以手动在 package.json 文件中,在 browserslist 属性下对开发环境和生产环境进行不同程度的浏览器清单兼容配置:

// package.json 文件(JSON文件不支持包含注释,实际使用请去掉注释)
{
  "name": "webpack-study",
  "version": "1.0.0",
  "description": "",
  "main": "index2.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
  },
  "author": "可乐",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^5.0.1",
    "file-loader": "^6.2.0",
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.1",
    "less": "^4.0.0",
    "less-loader": "^7.2.1",
    "mini-css-extract-plugin": "^1.3.4",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^4.44.2",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  },
  // 浏览器清单兼容配置
  "browserslist": {
    // 开发环境配置
    "development": [
      "last 1 chrome version", // 只兼容到上一个版本的谷歌浏览器
      "last 1 firefox version", // 只兼容到上一个版本的火狐浏览器
      "last 1 safari version" // 只兼容到上一个版本的safari浏览器
    ],
    // 生产环境配置
    "production": [
      ">0.1%", // 只对市场份额大于 0.1% 浏览器进行兼容
      "not dead", // 不兼容已死掉的浏览器
      "not op_mini all" // 不兼容所有 Opera Mini 浏览器(该浏览器依旧有使用群体,可根据实际情况配置)
    ]
  }
}

接着我们要在 webpack.config.js 文件中利用 process.env.NODE_ENV (node 中的 process 对象类似于浏览器中的 window 对象)修改 node 当前的环境变量:(注意:postcss-preset-env 插件读取的不是当前配置的 webpack 的 mode,而是 node 的环境变量)

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');


// 设置 node 环境变量 ( development 或 production )
process.env.NODE_ENV = 'production';

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 打包样式资源 
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
          {
            loader: 'postcss-loader', // 对 css 进行兼容性处理
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')() // 使用 postcss-preset-env 插件根据当前 node 环境变量对 css 按指定条件进行处理
              ]
            }
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    })
  ],
  mode: 'development'
}

接着运行 webpack,你会发现弹性盒子也被做了兼容性处理,如果你所设置的市场份额为 >0%,它会兼容所有版本的浏览器,对 border-radius 这样的样式都会做兼容性处理:

对于生产环境的浏览器兼容配置,官方推荐的写法是这样:

{
  "name": "webpack-study",
  "version": "1.0.0",
  "description": "",
  "main": "index2.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
  },
  "author": "可乐",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^5.0.1",
    "file-loader": "^6.2.0",
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.1",
    "less": "^4.0.0",
    "less-loader": "^7.2.1",
    "mini-css-extract-plugin": "^1.3.4",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^4.44.2",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      "last 1 version",
      "> 1%",
      "maintained node versions",
      "not dead"
    ]
  }
}

想要了解更多的 browserslist 配置,可阅读该文档 https://github.com/browserslist/browserslist#readme 。

3.3 压缩CSS文件

生产环境对 css 进行的最后一步处理,就是进行文件压缩。在 webpack 中对 css 的压缩处理非常简单,我们只需要引入 optimize-css-assets-webpack-plugin 插件,然后在 plugins 中实例化一下就好了。这里就不多说了,直接上代码:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 压缩 css

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 打包样式资源 
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
          {
            loader: 'postcss-loader', // 对 css 进行兼容性处理
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')() // 读取 postcss-preset-env 插件的环境变量
              ]
            }
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    }),
    // 压缩css
    new OptimizeCssAssetsWebpackPlugin()
  ],
  mode: 'development'
}

3.4 对JS进行兼容性处理

现在的主流浏览器基本支持新一代 ES6 语法,不过老版本的浏览器很多都不能解析 ES6 语法,这种时候我们就需要对 JS 进行兼容性处理,将 ES6 语法编译成老版本浏览器可以识别的 ES5 甚至 ES3 语法。对 JS 进行兼容性处理,我们需要使用到 babel-loader,这个 loader 依赖于一个核心库 @babel/core,所以我们需要同时下载这个库:

npm i babel-loader @babel/core --save-dev

对JS代码进行兼容分三种情况:

第一种情况是只做基本的兼容,它可以将 let、const 之类的关键字,转换为老版本浏览器可以识别的 var 关键字,我们需要安装一个 @babel/preset-env 的依赖包,指示 babel 以该规则进行兼容:

npm i @babel/preset-env --save-dev

接着我们修改 webpack.config.js 文件如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 对js进行兼容性处理
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 指示babel按 preset-env 的规则进行基本的兼容处理
          presets: [
            [
              '@babel/preset-env'
            ]
          ]
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

现在我们写一些 ES6 语法的代码,然后运行 webpack:

我们可以看到打包出来的代码,成功将箭头函数转换成了普通函数,但是它无法处理全新的 ES6 机制的东西,如 Promise 对象。

第二种兼容JS的情况,是进行完整的JS兼容,对所有主流浏览器的版本以及所有全新的ES6语法进行兼容。要实现这种全盘兼容,我们需要安装一个名为 @babel/polyfill 的库:

npm i @babel/polyfill --save-dev

安装完成后,我们要应用该库,并不需要在 webpack.config.js 文件进行配置,只要在入口文件头部引入它:

然后运行 webpack,你会发现打包后的 js 文件体积变得非常的巨大,从原来的 4kb 直接变成了 504kb,打包出来的文件也多了很多兼容代码:

我们并不总是希望代码体量如此庞大,这其中会产生很多没有必要的代码。如果我们希望根据自己的项目需求,对指定的浏览器版本进行兼容,这时就需要安装一个叫 core-js 的库了:

npm i core-js --save-dev

这个库包含了对所有浏览器的兼容性代码。但有一个好处在于,它支持按需引入。安装完成后,我们需要在 webpack.config.js 中进行如下配置:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [ 
      // 对js进行兼容性处理
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                // 指定兼容方式, 配置为'usage'实现按需加载
                useBuiltIns: 'usage',
                // 指定core-js版本
                corejs: {
                  version: 3
                },
                // 指定兼容某个版本之后的浏览器
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ]
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

重新运行一下 webpack,你会看到打包后的代码体积直接缩小到119kb了。如果你没有配置 targets 属性,则该插件会根据 package.json 里的 browserslist 属性进行兼容。想要对这些相关属性进行更多的了解,推荐阅读 Babel 7 升级实践 。

3.5 压缩JS文件

css 需要压缩,js 就更不用说了。在 webpack4+ 后的版本里,压缩 js 的写法变得非常的容易了。我们只需要修改 mode 为生产环境即可:

const { resolve } = require('path');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'dist')
  },
  // webpack4+ 将 mode 设为 production 即可压缩 js 文件
  mode: 'production'
};

配置为生产模式,你就可以看到打包后的 built.js 被压缩了:

3.6 压缩HTML文件

压缩 html 也很简单,我们只需在原来的 html-webpack-plugin 插件的实例中设置 minify 属性即可:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'dist')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      // 压缩 html文件
      minify: true
    })
  ],
  mode: 'production'
};

该属性还允许进行自定义配置,如:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'dist')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      // 压缩 html文件
      minify: {
        collapseWhitespace: true, // 移除空格
        removeComments: true // 移除注释
      }
    })
  ],
  mode: 'production'
};

3.7 生产环境配置总结

最后,我们前面描述的这些配置,结合一下开发环境的配置进行总结,就能得到生产环境的基本总配置了:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');

// 设置 node 环境变量
process.env.NODE_ENV = 'production';

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // 单独抽离css文件并进行兼容性处理
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader, // 单独抽离css文件
          'css-loader',
          'less-loader',
          {
            loader: 'postcss-loader', // 对 css 进行兼容性处理(需要配置 package.json 文件的 browserslist 属性)
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')() // 读取 postcss-preset-env 插件的环境变量
              ]
            }
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader, // 单独抽离css文件
          'css-loader',
          {
            loader: 'postcss-loader', // 对 css 进行兼容性处理(需要配置 package.json 文件的 browserslist 属性)
            options: {
              ident: 'postcss',
              plugins: () => [
                require('postcss-preset-env')() // 读取 postcss-preset-env 插件的环境变量
              ]
            }
          }
        ]
      },
      // 对js进行兼容性处理
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 预设:指示babel做怎么样的兼容性处理
          presets: [
            [
              '@babel/preset-env',
              {
                // 按需加载
                useBuiltIns: 'usage',
                // 指定core-js版本
                corejs: {
                  version: 3
                },
                // 指定兼容性做到哪个版本浏览器
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ]
        }
      },
      {
        test: /\.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          outputPath: 'imgs',
          esModule: false
        }
      },
      {
        test: /\.html$/,
        loader: 'html-loader' // 处理 html文件 src 属性引入的图片资源
      },
      {
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // 压缩html文件
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true, // 移除空格
        removeComments: true // 移除注释
      }
    }),
    new MiniCssExtractPlugin({
      filename: 'css/index.css' // 对抽离的css文件进行重命名
    }),
    // 压缩css
    new OptimizeCssAssetsWebpackPlugin(),
    // 配置JS检查规则
    new ESLintPlugin({
      fix: true, // 对打包生成的文件自动纠错
      extensions: ['js', 'json'], // 只检查 js、json 结尾的文件
      exclude: '/node_modules/' // 排除 node_modules
    })
  ],
  // 生产环境默认压缩js文件
  mode: 'production'
}
// package.json 文件 (实际使用时请把注释语句全部去掉)
{
  "name": "webpack-study",
  "version": "1.0.0",
  "description": "",
  "main": "index2.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
  },
  "author": "可乐",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.12.13",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.12.13",
    "babel-loader": "^8.2.2",
    "core-js": "^3.8.3",
    "css-loader": "^5.0.1",
    "eslint": "^7.19.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-webpack-plugin": "^2.4.3",
    "file-loader": "^6.2.0",
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.1",
    "less": "^4.0.0",
    "less-loader": "^7.2.1",
    "mini-css-extract-plugin": "^1.3.4",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^2.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^4.44.2",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      "last 1 version",
      "> 1%",
      "maintained node versions",
      "not dead"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base",
    "rules": {
      "no-console": "off"
    },
    "env": {
      "browser": true
    }
  }
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值