安装 Node 环境

工程化项目的搭建依赖于 Node 环境,因此需要先安装Node环境。

安装 node.js

进入 https://nodejs.org/en/download/ 根据自己电脑的系统不同,下载对应的安装文件,进行安装

设置 npm 镜像源

npm是Node.js的包管理工具,由于node下载第三方依赖包都是从国外服务器下载,下载的速度十分缓慢且有可能会出现异常。为了提高效率,我们可以把 npm 的镜像源替换成淘宝的镜像源:npm config set registry https://registry.npm.taobao.org

搭建过程

1、初始化工程

新建工程目录

  1. mkdir webpack-demo

进入工程目录

cd webpack-demo

初始化npm配置文件

npm init

安装 webpack

npm install --save-dev webpack # 安装核⼼库
npm install --save-dev webpack-cli # 安装命令⾏⼯具

2、配置npm镜像源

使用npm安装第三方依赖包都是从国外的服务器下载的,其速度十分缓慢,我们可以使用 npm config set registry [https://registry.npm.taobao.org](https://registry.npm.taobao.org) 命令将npm源设置为淘宝的镜像源。但是,如果某个同学克隆了了你的项⽬之后,准备在他本地开发的时候,并没有设置淘宝镜像源,⼜要⼈家去⼿动设置⼀遍,我们作为项⽬的发起者,就先给别⼈省下这份时间吧,我们只需要在根⽬录 添加⼀个 .npmrc 文件并做简单的配置即可:

# 创建 .npmrc ⽂件
touch .npmrc


# 在该⽂件内输⼊配置
registry=https://registry.npm.taobao.org/

3、创建src目录及入口文件

在根目录下创建 src 目录,并在 src 目录下创建入口文件 index.js

# 创建 src 目录
mkdir src


#在src 目录下创建入口文件 index.js
touch index.js

4、创建 webpack 配置文件

在根目录下创建 webpack.config.js 配置文件,并在配置文件中先编写默认的配置

创建 webpack.config.js 文件

touch webpack.config.js

编写默认配置

const path = require('path');
module.exports = {
    entry: "./src/index.js",
  output: {
      path: path.resolve(__dirname, "./dist"),
    filename: "[name].js",
  },
  mode: "development",
};

5、集成CSS样式处理

安装 css-loader style-loader

npm install style-loader css-loader -D

配置CSS
在 webpack.config.js 文件中配置 CSS

module: {
    rules: [
    {
        test: /\.css$/,
      use: ["style-loader", "css-loader"],
    },
  ],
},

6、集成 less sass

可根据项目需要安装 less 或 sass

安装 less sass

# 安装 less
npm install less less-loader -D

# 安装 sass
npm install node-sass sass-loader -D

配置 less sass

module: {
    rules: [
    {
        test: /\.less$/,
      use: ["style-loader", "css-loader", "less-loader"],
    },
    {
        test: /\.scss$/,
      use: ["style-loader", "css-loader", "sass-loader"],
    },
  ],
},

7、集成 postcss

postcss 的主要功能有两个,第一是把 css 解析成 JS 可以操作的抽象语法树 AST,第二就是调用插件来处理 AST 并得到结果。所以 postcss 一般都是通过插件来处理css,比如自动补齐浏览器前缀,使用 autoprefixer 插件来处理,压缩 css 使用 cssnano 插件来处理。

配置 autoprefixer

在根目录下创建 postcss.config.js 文件,在文件里编写配置:

module.exports = {
    plugins: [require('autoprefixer')]
}

添加上面的配置后,autoprefixer 并不会生效,还需要给 autoprefixer 添加浏览器清单配置。

方式一:在 package.json 文件配置
在 package.json 中添加 browserslist 属性

"browserslist":["last 2 versions", "> 1%", "not ie <= 8"],

方式二:在 postcss.config.js 文件中配置

module.exports = {
 plugins: [
   require("autoprefixer")({
       overrideBrowserslist: ["last 2 versions", "> 1%", "not ie <= 8"],
      }),
 ],
};

方式三:在 .browserslistrc ⽂件中配置

> 1%
last 2 versions
not ie <= 8

其中,在 package.json 文件和 .browserslistrc 文件中配置的浏览器清单会作用于整个项目,在 postcss.config.js 文件中配置的浏览器清单只作用于 autoprefixer 自身。

8、样式文件分离

经过 css-loader、style-loader、less-loader、sass-loader 处理后的 css 最终是打包在 js 中的,运行时会动态插入到 head 标签中。但是在生产环境中,一般都是将 css 文件分离出来,这样就有利于客户端缓存,并行加载及减少 js 包的大小。这时候就要用到 mini-cssextract-plugin 插件。

在 webpack.config.js 文件中添加配置:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          // 插件需要参与模块解析,须在此设置此项,不再需要style-loader
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: true, // 模块热替换,仅需在开发环境开启
              // reloadAll: true,
              // ... 其他配置
            }
          },
          'css-loader',
          'postcss-loader',
          'less-loader'
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css', // 输出⽂件的名字
      // ... 其他配置
    }),
  ]
};

9、图片/文字处理

url-loader 和 file-loader 都可以用来处理本地的资源文件,如图片、字体、音视频等。两者功能都是类似的,但 url-loader 可以指定 在文件大小低于指定的限制时,返回一个 DataURL,即将文件转义成base64,并不会输入真实的文件,这样就可以减少昂贵的网络请求,从而达到性能优化的目的。

安装 url-loader file-loader

npm install url-loader file-loader -D

配置 url-loader file-loader

module.exports = {
  modules: {
    rules: [
      {
        test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'url-loader', // 仅配置url-loader即可,内部会⾃动调⽤file-loader
            options: {
              limit: 10240, //⼩于此值的⽂件会被转换成DataURL
              name: '[name]_[hash:6].[ext]', // 设置输出⽂件的名字
              outputPath: 'assets', // 设置资源输出的⽬录
            }
          }
        ],
        exclude: /node_modules/
      }
    ]
  }
}

默认情况下,使用 file-loader 生成的文件的文件名是文件内容的 MD5 哈希值,我们可以通过设置 file-loader 的 options 对象中的 name 属性来设置输出的文件名与原文件名保持一致,如下配置:

{
  loader: 'file-loader',
  options: {
    // [path] 文件资源的相对路径
    // [name] 文件名
    // [ext] 文件扩展名
    name: '[path][name].[ext]'
  }
}

注意
url-loader 的 limit 设置要设置合理,太大会导致 JS 文件加载变慢,需要兼顾加载速度和网络请求次数。如果需要使用图片压缩功能,可以使用 image-webpack-loader

10、html 页面处理

HtmlWebpackPlugin 会在打包结束后,自动生成一个 HTML5 文件,并把打包生成的 js 模块引入到该 HTML 文件中。

例如我们在 webpack 中的配置如下:

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

const webpackConfig = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin()]
};

webpack 打包后生成的 HTML5 文件如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>webpack App</title>
  </head>
  <body>
    <script src="index_bundle.js"></script>
  </body>
</html>

安装 HtmlWebpackPlugin

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

HtmlWebpackPlugin 的配置项

title: ⽤来⽣成⻚⾯的 title 元素
filename: 输出的 HTML ⽂件名,默认是 index.html, 也可以直接配置带有⼦⽬录。
template: 模板⽂件路径,⽀持加载器,⽐如 html!./index.html
inject: true | 'head' | 'body' | false ,注⼊所有的资源到特定的 template 或者
templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body元素的底部,'head' 将放置到 head 元素中。
favicon: 添加特定的 favicon 路径到输出的 HTML ⽂件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加⼀个唯⼀的 webpack 编译 hash 到所有包含的脚本和CSS ⽂件,对于解除 cache 很有⽤。
cache: true | false,如果为 true, 这是默认值,仅仅在⽂件修改之后才会发布⽂件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写⼊到 HTML ⻚⾯中
chunks: 允许只添加某些块 (⽐如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到⻚⾯之前的排序⽅式,⽀持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(⽐如,跳过单元测试的块)

HtmlWebpackPlugin 配置案例

Tip: 上述 loader 的集成可根据项目需要进行配置使用。

到这里,一个简单的前端工程化项目基本搭建完成了。