1. webpack介绍 #

Webpack 是一个强大的模块打包器(module bundler),它可以把各种资源,如 JavaScript、CSS、图片等都作为模块来处理和使用。Webpack 会从一个或多个“入口”出发,识别出源文件间的依赖关系,然后将这些资源转换和打包成浏览器可接受的静态资源(通常是 JavaScript、CSS 文件等)。

2. webpack的安装 #

在安装和使用 Webpack 之前,你需要首先确保你的系统中已经安装了 Node.js 和 npm(Node.js 包管理器)。你可以在 Node.js 官方网站 https://nodejs.org/ 下载并安装 Node.js,npm 会随同 Node.js 一起安装。

安装 Node.js 和 npm 后,你可以使用 npm 来安装 Webpack。为了在任何地方都能运行 Webpack,你可以全局安装它:

npm install --global webpack

然而,在大多数项目中,你可能希望将 Webpack 安装为项目的开发依赖。这样可以确保项目的每个开发人员都使用相同的 Webpack 版本。你可以使用以下命令在项目中安装 Webpack:

npm install --save-dev webpack

这将会把 Webpack 安装在你的项目目录中的 node_modules 文件夹下,并且在 package.json 文件中添加一个 devDependencies(开发依赖)条目。

此外,你可能还需要安装 webpack-cli(Webpack 命令行接口)。Webpack CLI 提供了很多命令行选项,使你能够更方便地使用 Webpack:

npm install --save-dev webpack-cli

现在,你应该可以在命令行中运行 webpack 命令了。为了测试这一点,你可以创建一个 JavaScript 文件(例如 index.js),然后在命令行中运行 webpack 命令:

webpack index.js

如果一切正常,Webpack 应该会生成一个 dist/main.js 文件,这个文件包含了 index.js 文件的打包结果。

3. 配置文件 #

Webpack是一个非常强大的前端资源打包工具,它可以将众多前端资源(如:js、css、图片等)打包为一个或者多个bundle。 Webpack主要通过配置文件(webpack.config.js)来完成工作。

以下是一个基础的webpack.config.js配置文件的样子:

const path = require('path');

module.exports = {

};

4. entry #

在 Webpack 的配置中,entry 选项是用来指定 Webpack 应该使用哪个文件作为构建内部依赖图的开始。换句话说,entry 是指定 Webpack 从哪个文件开始打包的地方。

entry 可以是一个字符串、一个数组或者一个对象。

1. 字符串

这是最简单的情况。当 entry 是一个字符串时,它指向项目的主文件(也称为主模块)。

module.exports = {
  entry: './src/index.js'
};

2. 对象

如果你的项目有多个独立的入口,你可以使用一个对象来设置 entry。对象的每一个键值对都代表一个入口。

module.exports = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

在这个配置中,Webpack 会生成两个独立的打包文件,一个是 app.js 的打包文件,另一个是 vendors.js 的打包文件。生成的打包文件的名称与 entry 对象的键名对应。

这样的配置非常适合于单页面应用(SPA),你可以把应用的代码和第三方库的代码分别打包到不同的文件中,以便进行缓存和更新。

注意,如果 entry 没有被设置,Webpack 将使用默认值 ./src/index.js

5. output #

Webpack的output配置项用于设置如何以及在哪里输出打包后的文件。

这是一个output的基础使用示例:

output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
}

这个配置的意思是:Webpack将打包好的文件输出为main.js,并将它存放在dist目录下。这里的path.resolve(__dirname, 'dist')用来获取当前目录下名为dist的子目录的绝对路径。在Node.js中,__dirname是当前模块文件所在目录的绝对路径。

让我们来详细解析一下output对象的各个属性:

6. html-webpack-plugin #

在Webpack中,插件用于完成加载器无法实现的各种功能。html-webpack-plugin就是Webpack中一个非常常用的插件,它可以创建一个HTML文件,然后把Webpack打包后的所有入口点(bundles)都自动添加到这个HTML文件中。

首先,你需要安装这个插件。你可以在项目目录下运行以下命令进行安装:

npm install --save-dev html-webpack-plugin

然后在webpack.config.js中,引入html-webpack-plugin并在plugins数组中实例化:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

在这个例子中,插件将会创建一个新的HTML文件,这个文件是根据src/index.html这个模板创建的。然后插件会把所有Webpack打包后的入口点自动添加到这个新的HTML文件中。

7. 开发服务器 #

在Webpack 5中,开发服务器是一个用于开发环境的工具,它可以实时监测源代码的更改并自动重新编译和刷新页面,以提供更快的开发体验。以下是关于Webpack 5开发服务器的一些重要信息和使用方法。

  1. 安装开发服务器: 在使用Webpack 5之前,你需要安装Webpack和Webpack开发服务器。可以使用npm或者yarn执行以下命令来安装它们:

    npm install webpack webpack-cli webpack-dev-server --save-dev
    

    或者

    yarn add webpack webpack-cli webpack-dev-server --dev
    
  2. 配置Webpack开发服务器: 在Webpack配置文件中,你需要指定开发服务器的相关配置。通常,这些配置被称为devServer。以下是一个简单的Webpack配置文件示例: static配置项允许配置从目录提供静态文件的选项(默认是 'public' 文件夹)。将其设置为 false 以禁用

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
        compress: true,
        port: 8080
    },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

  1. 启动开发服务器: 在项目根目录下执行以下命令来启动开发服务器:

    npx webpack serve
    

    或者

    yarn webpack serve
    

    这将启动开发服务器并监听源代码的更改。一旦检测到更改,它将自动重新编译和刷新页面。

  2. 访问开发服务器: 一旦开发服务器启动,你可以通过在浏览器中访问http://localhost:8080(默认情况下)来预览你的应用程序。如果你在Webpack配置文件中指定了不同的端口号,需要相应地更改URL中的端口号。

开发服务器还提供了许多其他功能,例如Hot Module Replacement(热模块替换),它可以在不刷新整个页面的情况下替换修改的模块,以提高开发效率。你可以在Webpack的官方文档中找到更多关于开发服务器的详细信息:https://webpack.js.org/configuration/dev-server/

8. 配置CSS #

在Webpack 5中配置CSS,需要做一些额外的配置。下面是一些步骤:

首先,你需要安装一些必要的加载器和插件。在此示例中,我们将使用css-loaderstyle-loader。这些都可以使用npm进行安装。

在你的项目目录下运行以下命令:

npm install --save-dev css-loader style-loader

css-loader解析CSS文件后,使用import加载,并且返回CSS代码。style-loader将模块的导出作为样式添加到DOM中。

然后,在webpack.config.js文件中,你需要添加一个新的规则来使用这些加载器:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
        compress: true,
        port: 8080
    },
+   module: {
+       rules: [
+           {
+               test: /\.css$/,
+               use: ['style-loader', 'css-loader'],
+           },
+       ],
+   },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

这段代码表示Webpack将使用style-loadercss-loader来处理任何.css文件。

现在,你就可以在你的JavaScript文件中import CSS文件了。例如:

src\index.js

import './styles.css';

src\styles.css

body{
  background-color: lightgreen;
}

这将把styles.css文件的内容作为样式添加到你的应用中。

9. 配置less #

要在Webpack 5中配置LESS,我们需要使用 less-loader,它允许你在Webpack构建中导入.less文件,并将它们编译为CSS。首先,我们需要安装一些必要的加载器:

npm install --save-dev less less-loader css-loader style-loader

然后,你需要在 webpack.config.js 文件中配置这些加载器:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
        compress: true,
        port: 8080
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
+           {
+               test: /\.less$/,
+               use: [
+                 {
+                   loader: 'style-loader', // creates style nodes from JS strings
+                 },
+                 {
+                   loader: 'css-loader', // translates CSS into CommonJS
+                 },
+                 {
+                   loader: 'less-loader', // compiles Less to CSS
+                 }
+               ]
+           }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

这段代码告诉Webpack对于任何 .less 文件,首先使用 less-loader 将其编译为 CSS,然后使用 css-loader 将 CSS 转换为 CommonJS(这使得我们可以使用 import 引入 CSS),最后使用 style-loader 将样式添加到 DOM 中。

现在,你就可以在 JavaScript 文件中导入 LESS 文件了。例如:

src\styles.less

@color:red;
body{
    color:@color;
}

src\index.js

import './styles.css';
+import './styles.less';

这将会将 styles.less 文件的内容编译为 CSS,并添加到你的应用中。

10. 配置sass #

要在Webpack 中配置Sass,我们需要使用 sass-loader,它允许你在Webpack构建中导入.scss或.sass文件,并将它们编译为CSS。首先,我们需要安装一些必要的加载器和Sass本身:

npm install --save-dev sass sass-loader css-loader style-loader

然后,你需要在 webpack.config.js 文件中配置这些加载器:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
        compress: true,
        port: 8080
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /\.less$/,
                use: [
                  {
                    loader: 'style-loader', // creates style nodes from JS strings
                  },
                  {
                    loader: 'css-loader', // translates CSS into CommonJS
                  },
                  {
                    loader: 'less-loader', // compiles Less to CSS
                  },
                ],
            },
+           {
+             test: /\.(scss|sass)$/,
+             use: [
+               {
+                 loader: 'style-loader', // creates style nodes from JS strings
+               },
+               {
+                 loader: 'css-loader', // translates CSS into CommonJS
+               },
+               {
+                 loader: 'sass-loader', // compiles Sass to CSS
+               },
+             ],
+           },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

这段代码告诉Webpack对于任何 .scss.sass 文件,首先使用 sass-loader 将其编译为 CSS,然后使用 css-loader 将 CSS 转换为 CommonJS(这使得我们可以使用 import 引入 CSS),最后使用 style-loader 将样式添加到 DOM 中。

现在,你就可以在 JavaScript 文件中导入 Sass 文件了。例如:

src\styles.scss

$fontSize:48px;
body{
    font-size:$fontSize;
}

src\index.js

import './styles.css';
import './styles.less';
+import './styles.scss';

这将会将 styles.scss 文件的内容编译为 CSS,并添加到你的应用中。

mini-css-extract-plugin 是一个 webpack 插件,用于将 CSS 从 JavaScript 文件中分离出来,生成单独的 CSS 文件。这在生产环境中尤其有用,因为将 CSS 分离到单独的文件中,可以使 CSS 和 JavaScript 并行加载,提高页面加载速度。

在 webpack 5 中使用 mini-css-extract-plugin,需要先通过 npm 或 yarn 安装:

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

或者

yarn add --dev mini-css-extract-plugin

安装完成后,需要在 webpack 配置文件中引入并使用它。下面是一个基础的示例:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
};

在这个例子中,我们首先引入了 mini-css-extract-plugin,然后在 module.rules 中,我们设置了对所有 CSS 文件使用 MiniCssExtractPlugin.loadercss-loader,这样 CSS 文件就会被处理并分离到单独的文件中。

接着,我们在 plugins 配置项中添加了一个 MiniCssExtractPlugin 实例。filename 选项用来指定生成的 CSS 文件的名称,[name][contenthash] 是 webpack 的占位符,分别表示模块的名字和模块内容的 hash 值。这样每个 CSS 文件的名称都将是唯一的。

请注意,这个插件应该只在生产环境中使用,在开发环境中,你可能需要使用 style-loader 来将 CSS 插入到 JavaScript 中,以便实现热替换。

11. postcss #

PostCSS是一个用JavaScript工具和插件转换CSS代码的工具。postcss-loader允许你在Webpack中使用PostCSS。

首先,你需要安装postcss-loaderpostcss

npm install --save-dev postcss-loader postcss

然后,在webpack.config.js文件中,你需要添加一个新的规则来使用这个加载器:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
        compress: true,
        port: 8080
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                  'style-loader', 
                  'css-loader',
+                 {
+                   loader: 'postcss-loader',
+                   options: {
+                     postcssOptions: {
+                       plugins: [
+                         [
+                           'autoprefixer',
+                           {
+                             overrideBrowserslist: ['> 1%', 'last 2 versions']
+                           }
+                         ]
+                       ]
+                     }
+                   }
+                 },
                ],
            },
            {
                test: /\.less$/,
                use: [
                  {
                    loader: 'style-loader', // creates style nodes from JS strings
                  },
                  {
                    loader: 'css-loader', // translates CSS into CommonJS
                  },
+                 {
+                   loader: 'postcss-loader',
+                   options: {
+                     postcssOptions: {
+                       plugins: [
+                         [
+                           'autoprefixer',
+                           {}
+                         ]
+                       ]
+                     }
+                   }
+                 },
                  {
                    loader: 'less-loader', // compiles Less to CSS
                  },
                ],
            },
            {
              test: /\.(scss|sass)$/,
              use: [
                {
                  loader: 'style-loader', // creates style nodes from JS strings
                },
                {
                  loader: 'css-loader', // translates CSS into CommonJS
                },
+               {
+                 loader: 'postcss-loader',
+                 options: {
+                   postcssOptions: {
+                     plugins: [
+                       [
+                         'autoprefixer',
+                         {}
+                       ]
+                     ]
+                   }
+                 }
+               },
                {
                  loader: 'sass-loader', // compiles Sass to CSS
                },
              ],
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
          template: 'src/index.html'
        }),
    ]
};

在上述配置中,Webpack将使用style-loadercss-loaderpostcss-loader来处理任何.css文件。我们在PostCSS的配置中指定了一个插件 - 'autoprefixer',这是一个自动添加CSS前缀的插件,用于增加CSS的浏览器兼容性。注意,你需要自行安装所需要的PostCSS插件,例如在这里,你需要安装autoprefixer:

npm install --save-dev autoprefixer

现在,你就可以在你的JavaScript文件中import CSS文件了。例如:

src\styles.css

body {
    background-color: lightgreen;
}

+.postcss {
+    display: flex;
+    box-sizing: border-box;
+}

src\index.js

import './styles.css';
import './styles.less';
import './styles.scss';

src\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webpack</title>
</head>
<body>
    hello
+   <div class="postcss">postcss</div>
</body>
</html>

这将把styles.css文件的内容作为样式添加到你的应用中,并且在这个过程中,postcss-loader会处理你的CSS代码,例如添加必要的浏览器前缀。

12.加载静态资源 #

要在Webpack 5中加载静态资源如图片和字体,你需要使用合适的加载器,如 file-loaderurl-loader。然而,在Webpack 5中引入了新的特性:Asset Modules,这是一种内置的模块类型,允许你更方便地使用静态资源。

加载图片

你可以使用 asset/resource 类型处理图片,这将类似于以前使用 file-loader 的方式:

module.exports = {
  module: {
    rules: [
+     {
+       test: /\.(png|svg|jpg|jpeg|gif)$/i,
+       type: 'asset/resource',
+     }
    ]
  }
};

这里,任何 .png, .svg, .jpg, .jpeg, .gif 后缀的文件将作为资源被处理,并返回一个公共路径。

src\index.js

import './styles.css';
import './styles.less';
import './styles.scss';
import logo from './images/logo.jpg';
console.log(logo);

这将分别把 logo.jpg 作为资源添加到你的应用中,并返回它们的公共路径或内容。

13.babel #

13.1 安装Babel #

要在Webpack 5中配置Babel,我们需要使用 babel-loader,它使Webpack可以使用Babel转译JavaScript。此外,你也需要安装一些Babel的核心库和插件。

首先,安装必要的依赖:

npm install --save-dev babel-loader @babel/core @babel/preset-env

然后,在 webpack.config.js 文件中,你需要添加一个新的规则来使用这个加载器:

webpack.config.js

const path = require('path');
module.exports = {
  module: {
    rules: [
+     {
+       test: /\.m?js$/,
+       exclude: /(node_modules)/,
+       use: {
+         loader: 'babel-loader',
+         options: {
+           presets: ['@babel/preset-env'],
+         }
+       }
+     }
    ],
  },
};

这段配置告诉Webpack对所有 .js 文件(除了 node_modulesbower_components 目录中的文件)使用 babel-loaderbabel-loader 会使用 @babel/preset-env 预设将这些文件中的ES6+代码转译为ES5代码。

以上是在Webpack 5中配置Babel的基本步骤。如果你需要更复杂的配置,例如使用Babel插件或其他预设,你可以创建一个 .babelrc 文件或在 package.json 文件中添加一个 babel 字段,然后在那里写入你的Babel配置。例如:

// .babelrc

{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

在上述例子中,我们还添加了 @babel/plugin-proposal-class-properties 插件,它允许你在你的代码中使用类属性语法。当然,你需要安装这个插件:

npm install --save-dev @babel/plugin-proposal-class-properties
  1. babel-loader:这是Webpack的一个加载器,它允许Webpack调用并运行Babel。当Webpack遇到一个JavaScript文件时,它将使用babel-loader将这个文件传递给Babel进行转译。

  2. @babel/core:这是Babel的核心库,它实际上执行了转译的工作。@babel/core使用你提供的配置(例如预设和插件)来决定如何转译代码。

  3. @babel/preset-env:这是Babel的一个预设,它根据你指定的目标环境自动决定你需要哪些Babel插件。例如,如果你的目标环境是最新的两个浏览器版本,@babel/preset-env 将只包含转译那些新浏览器还不支持的JavaScript特性的插件。

  4. .babelrc:这是一个Babel的配置文件,你可以在这里指定你想要使用的预设和插件。你也可以选择在package.json文件中提供一个babel字段作为配置,但你不应同时使用两者。

以下是.babelrc配置文件中的一些关键部分:

你可以根据你的需求来选择使用哪些预设和插件。如果你不确定你需要什么,@babel/preset-env 是一个很好的开始,因为它会自动选择适合你的目标环境的插件。

// 使用 let 和 const 声明变量
const name = 'Alice';
let greeting = 'Hello';

// 使用模板字符串
console.log(`${greeting}, ${name}!`);

// 使用箭头函数
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(number => number * number);
console.log(squared);

// 使用 Promise
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise resolved');
  }, 1000);
});

promise.then(value => console.log(value));

// 使用对象扩展运算符
const obj1 = { foo: 'bar', x: 42 };
const obj2 = { foo: 'baz', y: 13 };

const mergedObject = { ...obj1, ...obj2 };
console.log(mergedObject);

// 使用类
class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person = new Person('Bob');
person.greet();

13.2 presets和plugins #

Babel 是一个 JavaScript 编译器,它通过一系列的插件(plugins)和预设(presets)转换 JavaScript 代码。插件和预设是 Babel 工作的核心部分,它们定义了 Babel 如何进行代码转换。

Babel 插件(plugins)

Babel 插件是实现代码转换的实际工具。每一个 Babel 插件都对应一个特定的 JavaScript 语言特性,比如 @babel/plugin-transform-arrow-functions 插件将 ES6 的箭头函数转换为 ES5 的函数表达式。你可以按需选择需要的插件进行配置。

Babel 预设(presets)

因为 JavaScript 新特性众多,如果每个特性都用一个插件来进行转换,那么配置起来就会很麻烦。Babel 预设实际上是一个插件的集合,它包含了一组插件来支持某一特定的 JavaScript 版本或一些特定的语言特性。比如 @babel/preset-env 预设包含了所有最新的 JavaScript 语言特性的插件。

预设的目的是为了方便开发者使用,你只需要安装并配置对应的预设,Babel 就会自动使用预设中包含的所有插件进行代码转换。

关系

总的来说,Babel 插件和预设的关系就像工具和工具箱的关系。插件就是各种各样的工具,你可以单独使用它们;预设就是工具箱,它包含了一组工具,你可以一次性地获取所有工具。

在大多数情况下,我们会优先使用预设。这是因为预设能够更方便地管理插件,并且它们通常会包含所有我们需要的插件。然而,如果你需要对 Babel 的行为进行更细粒度的控制,或者你需要使用一些预设中没有包含的插件,那么你可能需要直接配置插件。

13.3 @babel/polyfill #

在编写 JavaScript 代码时,我们经常会使用一些新的 ES6+ 的特性,比如 PromiseArray.prototype.includes 等。但是,一些旧的浏览器并不支持这些新特性。这就是为什么我们需要 Babel 来将这些新特性转换为旧的、被所有浏览器支持的语法。

然而,Babel 默认只转换新的 JavaScript 语法,而不转换新的 API。比如,旧版的浏览器可能并没有实现 PromiseArray.prototype.includes,即使你使用 Babel 将你的代码转换为 ES5,这些代码在旧版浏览器中仍然会报错。

为了解决这个问题,我们可以使用 @babel/polyfill@babel/polyfill 是一个包含了 ES6+ 新 API 的 polyfill。当你在你的代码中引入 @babel/polyfill 时,它会改变全局作用域,像 Promise 这样的全局变量会被添加进来。这样你就可以在你的代码中直接使用这些新的 API 了。

然而,@babel/polyfill 已在 Babel 7.4.0 中被弃用,建议使用 core-jsregenerator-runtime 来替代。你可以在你的代码的入口文件中引入 core-jsregenerator-runtime

import "core-js/stable";
import "regenerator-runtime/runtime";

然后在 Babel 配置文件 .babelrcbabel.config.js 中配置 useBuiltIns'usage',这样 Babel 就会根据你的代码自动导入需要的 polyfill:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

在上面的配置中,useBuiltIns 选项设置为 'usage',这意味着只包括你需要用到的 polyfill,而不是所有的 polyfill,这可以减小最终打包文件的大小。corejs 选项设置为 3,表示使用 core-js@3 这个版本的 polyfill。

这样,你就可以在你的代码中放心地使用新的 ES6+ API 了。

const arr = [1, 2, 3, 4, 5];

console.log(arr.includes(2));  // 输出: true

const obj = {
  a: 1,
  b: 2,
  c: 3
};

console.log(Object.values(obj));  // 输出: [1, 2, 3]

14.ESLint #

要在Webpack 5中配置ESLint,你需要使用 eslint-loader。然而,请注意,从ESLint的v8版本开始,推荐使用eslint-webpack-plugin代替eslint-loader。因此,下面将以eslint-webpack-plugin为例进行讲解。

首先,安装必要的依赖:

npm install --save-dev eslint eslint-webpack-plugin

然后,在 webpack.config.js 文件中,你需要添加新的插件来使用ESLint:

这个插件将会自动在你的源码被打包之前运行ESLint。

ESLintPlugin 接收一个可选的 options 对象,你可以在这个对象中配置ESLint。例如,你可以指定应用ESLint的文件类型:

在这个例子中,ESLint将会应用于所有 .js.jsx 文件。

// webpack.config.js

const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
  plugins: [
    new ESLintPlugin({
        extensions: ["js", "jsx"]
    })
  ]
};

你还可以在一个 .eslintrc.* 文件中提供ESLint配置。例如:

.eslintrc.json

{
    "env": {
      "browser": true,
      "es2021": true,
      "node": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
      "ecmaVersion": 12,
      "sourceType": "module"
    },
    "rules": {
      "indent": ["error", 2],
      "quotes": ["error", "double"],
      "semi": ["error", "always"]
    }
  }

这个配置指定了一些环境、扩展、解析器选项和规则。例如,它指定代码必须使用两个空格进行缩进,使用双引号,且每个语句后必须有分号。

以上就是在Webpack中配置ESLint的基本步骤。如果你需要更复杂的配置,你可以查阅ESLint文档eslint-webpack-plugin文档

15.JS压缩 #

在Webpack 5中,可以使用TerserPlugin来进行JavaScript代码的压缩。TerserPlugin是Webpack的默认插件,专门用于压缩JavaScript。以下是配置的基本步骤:

首先,你需要在你的webpack.config.js文件中引入TerserPlugin。如果你没有安装,可以通过npm进行安装:

npm install terser-webpack-plugin --save-dev

然后在webpack.config.js文件中配置TerserPlugin,例如:

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // 丢弃控制台输出
          },
        },
      }),
    ],
  },
};

在这个配置中,mode: 'production'让webpack以生产模式运行,这时默认会启用JavaScript的压缩。

优化部分optimizationminimize设为true,表示开启压缩。

minimizer属性接收一个数组,数组中的每个元素都是一个压缩插件的实例。在这个例子中,我们添加了new TerserPlugin()实例。

compress选项是Terser压缩器的设置,drop_console: true表示在压缩代码时丢弃所有console.*函数的调用。

请注意,在生产环境中,Webpack 5默认使用TerserPlugin进行压缩。但如果你需要更改默认的压缩器设置或使用其他压缩插件,可以像上面这样进行配置。

更多TerserPlugin的配置选项,可以查看它的官方文档:https://webpack.js.org/plugins/terser-webpack-plugin/

16.CSS压缩 #

在Webpack 中,你可以使用css-minimizer-webpack-plugin来进行CSS代码的压缩。这是一个优化和压缩CSS资源的插件。

首先,你需要在项目中安装css-minimizer-webpack-plugin。如果你还没有安装,你可以使用npm进行安装:

npm install css-minimizer-webpack-plugin --save-dev

然后在webpack.config.js文件中配置css-minimizer-webpack-plugin,例如:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: [
      new CssMinimizerPlugin(),
    ],
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

在这个配置中,mode: 'production'让webpack以生产模式运行,这时默认会启用JavaScript的压缩。

optimizationminimize设为true,表示开启压缩。

minimizer属性接收一个数组,数组中的每个元素都是一个压缩插件的实例。在这个例子中,我们添加了new CssMinimizerPlugin()实例。

module.rules部分,我们为CSS文件配置了style-loadercss-loaderstyle-loader会将CSS注入到DOM中,css-loader会处理CSS中的import和url()。

在生产模式下,Webpack 会默认使用TerserPlugin进行JavaScript的压缩,但是并不会自动进行CSS的压缩,因此我们需要显式地添加css-minimizer-webpack-plugin插件。

更多css-minimizer-webpack-plugin的配置选项,可以查看它的官方文档:https://webpack.js.org/plugins/css-minimizer-webpack-plugin/

17.sourcemap #

在 Webpack 中,Source Map 是一个很重要的工具,它能够帮助我们在浏览器中更容易地调试代码。因为 Webpack 通常会对代码进行各种转换(比如 ES6 到 ES5),并且将多个文件打包成一个文件,这使得在浏览器中直接调试变得困难。这个时候,就需要用到 Source Map。

Source Map 是一个映射文件,它将编译、打包、压缩后的代码映射回原始的源代码。这意味着,即使你的代码已经被转换或者打包,你仍然可以看到原始代码的错误和日志,而不是转换或打包后的代码。这极大地方便了调试。

Webpack 提供了一个 devtool 配置选项,用于配置生成 Source Map 的方式。下面是一些常见的 devtool 选项:

module.exports = {
  devtool: 'inline-source-map',
  //...
};

上面的配置会生成一个内联的 Source Map,这个 Source Map 被编码成了 DataUrl,并且被包含在了最终的打包文件中。这种方式生成的 Source Map 包含了完整的列信息,可以方便地在浏览器中查看到原始代码,但是由于 Source Map 被包含在了打包文件中,会导致打包文件变大。

如果你不希望 Source Map 被包含在打包文件中,你可以使用下面的配置:

module.exports = {
  devtool: 'source-map',
  //...
};

这样会生成一个单独的 .map 文件,这个文件包含了 Source Map 信息,但是并不会被包含在打包文件中。

除了上面的两种方式,Webpack 还提供了许多其他的 devtool 选项,比如:

在开发环境中,通常推荐使用 eval-source-map,因为它提供了最详细的 Source Map。但是在生产环境中,由于需要考虑到代码的大小和重建速度,通常会使用 source-map 或者 cheap-module-source-map

18.配置代理 #

在 Webpack 中,代理主要通过 devServer.proxy 配置项来实现。这个配置项用于将某些 API 请求代理到不同的域名或端口,常用于解决开发环境中的跨域问题。

devServer.proxy 配置项是一个对象,键是需要代理的路径,值是目标服务器的配置信息。下面是一个简单的配置示例:

module.exports = {
  // ...
  devServer: {
    proxy: {
      '/api': 'http://localhost:3000'
    }
  }
};

在上面的配置中,所有以 /api 开头的请求,都会被代理到 http://localhost:3000 这个服务器上。例如,/api/users 这个请求,会被代理到 http://localhost:3000/api/users

你还可以提供更详细的配置项,例如,使用 target 来指定目标服务器,使用 changeOrigin 来修改原始主机头为目标 URL,或者使用 pathRewrite 来重写请求路径。下面是一个更详细的配置示例:

module.exports = {
  // ...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
};

在上面的配置中,target 选项用于指定目标服务器,changeOrigin 选项用于修改原始主机头为目标 URL,pathRewrite 选项用于重写请求路径。对于这个配置,/api/users 这个请求,会被代理并重写路径到 http://localhost:3000/users

这样,你就可以在开发环境中方便地解决跨域问题,而无需修改后端服务器的配置。在生产环境中,你应该确保你的服务器能够正确处理这些请求,而不是依赖于这个代理配置。

19.MPA多页面应用 #

多页面应用(MPA)是一个传统的 Web 开发模式,它包含了多个 HTML 页面,每个页面都对应一个入口点。Webpack 可以通过配置多个入口点和 HTML 插件,来构建多页面应用。

首先,你需要在配置文件中定义多个入口点。每个入口点对应一个 JS 文件,这个文件是构建每个页面的起点:

module.exports = {
  entry: {
    index: './src/index.js',
    about: './src/about.js',
    contact: './src/contact.js'
  },
  //...
};

在上面的配置中,我们定义了三个入口点,分别是 indexaboutcontact。每个入口点对应一个 JS 文件,这个文件是构建对应页面的起点。

接下来,你需要安装并配置 html-webpack-plugin。这个插件可以自动生成 HTML 文件,并自动引入所有的入口文件。对于每个页面,你都需要配置一个 html-webpack-plugin 实例:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  //...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      chunks: ['index'],
      template: './src/index.html'
    }),
    new HtmlWebpackPlugin({
      filename: 'about.html',
      chunks: ['about'],
      template: './src/about.html'
    }),
    new HtmlWebpackPlugin({
      filename: 'contact.html',
      chunks: ['contact'],
      template: './src/contact.html'
    })
  ]
};

在上面的配置中,我们为每个页面都配置了一个 html-webpack-plugin 实例。filename 选项定义了生成的 HTML 文件的名字,chunks 选项定义了需要引入的入口点,template 选项定义了 HTML 模板文件。

这样,Webpack 就会为每个入口点生成一个 HTML 文件,每个文件都会自动引入对应的入口文件。

这就是在 Webpack 中构建多页面应用的基本方式。在实际项目中,可能还需要根据项目需求,配置更多的加载器和插件。

20.使用vue2 #

npm install vue@2 --save

20.1 src\index.html #

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

20.2 src\main.js #

src\main.js

import Vue from "vue";
new Vue({
  el: "#app",
  render: h => h("div",null,"hello")
});

21.单文件组件 #

21.1 什么是单文件组件 #

在Vue 2中,单文件组件(Single File Components)是一种特殊的文件类型,其文件扩展名为.vue。一个.vue文件就是一个自包含的Vue组件,它包含该组件的模板、脚本和样式。下面是一个简单的例子:

<template>
  <div>
    <button @click="increment">+</button>
    <p>{{ count }}</p>
    <button @click="decrement">-</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    },
    decrement() {
      if (this.count > 0) {
        this.count--
      }
    }
  }
}
</script>

<style scoped>
button {
  margin-right: 10px;
}
</style>

这个.vue文件包含三部分:

请注意,你需要使用诸如Webpack之类的构建工具来处理这些.vue文件,因为浏览器并不能直接解析它们。你也需要安装和配置vue-loader,它是Webpack的一个加载器,可以将.vue文件转换为JavaScript模块。

单文件组件的优势在于它们允许你在一个文件中编写所有组件代码,这使得组织和管理复杂的Vue应用更为简单。你可以将组件逻辑、模板和样式放在一起,这有助于在团队中维持一致的代码风格,并使代码更易于理解。

21.2 配置vue-loader #

对于Vue 2,你应该使用vue-loader的v15.x版本。这个版本是专门为Vue 2设计的,包含了对单文件组件(.vue文件)的解析和编译支持。

你可以通过npm或者yarn来安装这个版本:

npm install -D vue-loader@^15 vue-template-compiler

或者

yarn add -D vue-loader@^15 vue-template-compiler

注意,你也需要安装vue-template-compiler。它的版本应该与vue核心库的版本一致。vue-template-compiler是用来预编译Vue 2的模板到渲染函数的。

此外,你还需要在你的Webpack配置中使用VueLoaderPlugin,这个插件是vue-loaderv15版本引入的。

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ESLintPlugin = require("eslint-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
+const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = {
  mode: "production",
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // 丢弃控制台输出
          },
        },
      }),
      new CssMinimizerPlugin(),
    ],
  },
+ entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js"
  },
  devServer: {
    static: {
      directory: path.join(__dirname, "public"),
    },
    compress: true,
    port: 8080
  },
  module: {
    rules: [
+     {
+       test: /\.vue$/,
+       loader: "vue-loader"
+     },
      ......
  plugins: [
    new HtmlWebpackPlugin({
      template: "src/index.html"
    }),
    new ESLintPlugin({
      extensions: ["js", "jsx"]
    }),
+    new VueLoaderPlugin()
  ]
};

这个插件必须包含在配置中,以便让Webpack理解.vue文件。

总的来说,对于Vue 2,你需要vue-loader的v15.x版本,以及配套的vue-template-compilerVueLoaderPlugin

22.@vue/cli #

@vue/cli是 Vue.js 的官方命令行工具,它提供了一种高效创建和管理 Vue.js 项目的方式。Vue CLI 在 3.0 版本后的架构进行了重大的改变,以提供更多的灵活性和更好的性能。

以下是一些主要的 Vue CLI 特性:

  1. 图形化项目管理:Vue CLI 提供了一个完整的图形化界面,使你可以不用编写任何命令行就能创建和管理项目。

  2. 可插拔的项目配置:Vue CLI 3.0+ 引入了插件的概念,允许你轻松地向项目中添加或删除特性。

  3. 高效的依赖管理:Vue CLI 提供了一个稳健的依赖管理系统,可以确保所有的依赖都能够被准确、高效地管理。

  4. 即时原型开发:你可以使用 Vue CLI 快速构建 Vue 单文件组件的原型,而无需设置整个项目结构。

  5. 开箱即用的配置:Vue CLI 已经预先配置好了 Babel、ESLint 等工具,这使得你可以立即开始开发,而不需要花费时间去手动配置这些工具。

下面是一个使用 @vue/cli 创建新项目的基本步骤:

首先,你需要使用以下命令安装 Vue CLI:

npm install -g @vue/cli
# OR
yarn global add @vue/cli

然后,你可以使用 vue create 命令来创建一个新的项目:

vue create my-project

此命令将启动一个交互式的 UI,允许你选择预定义的配置或手动选择特性。

完成这些步骤后,你就有了一个新的 Vue.js 项目,可以使用以下命令来启动你的项目:

cd my-project
npm run serve

此命令将启动一个开发服务器,你可以在本地浏览器中查看你的项目。

注意,Vue CLI 是一个非常强大的工具,还有许多其他高级特性和配置选项,我这里只是简单介绍了一下。要获取更多信息,你可以查看 Vue CLI 的官方文档