# 用 webpack 搭建 Ming-cli

因为从 AS3 语言向 TS 转型,选用 webpack 作为打包工具,可以省略 LayaCMD 的编译时间从而高效率的提高工作效率。

# 业务需求

  • TS 支持
  • 分包
  • 断点调试
  • 重新加载

# 安装起步

npm(node package manager)是 nodejs 的包管理器,用于 node 插件管理(包括安装、卸载、管理依赖等),npm 安装插件过程:从http://registry.npmjs.org 下载对应的插件包(该网站服务器位于国外,所以经常下载缓慢或出现异常) 这时候我们就需要用到cnpm

cnpm是淘宝镜像服务器,来自官网:“这是一个完整npmjs.org镜像,你可以用此代替官方版本(只读),同步频率目前为 10 分钟 一次以保证尽量与官方服务同步。”

npm install -g cnpm --registry=https://registry.npm.taobao.org
1

开始安装webpack,目前最新的webpack版本为v4.27.1,因为使用版本为webpack 4+,还需要安装 CLI

npm install --save-dev webpack
npm install --save-dev webpack-cli
1
2

安装完成后,做些准备工作。打开package.json

  • 删除入口"main": "index.js"
  • 添加"private": true防止意外发布。
  • 添加"build": "webpack"npm 脚本快捷发布
{
  "name": "Ming-cli",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "zenosLin",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

新建配置文件webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};
1
2
3
4
5
6
7
8
9

现在一个由webpack组成的脚手架工具雏形已经完成。 如果需要在 js 中打包lodash依赖,我们需要在本地安装 library

npm install --save lodash
1

并在 js 文件中import _ from 'lodash'

# TypeScript 支持

安装 TypeScript 编译器和 loader:

npm install --save-dev typescript ts-loader
1

新建tsconfig.json文件

设置一个基本的配置,来支持 JSX,并将 TypeScript 编译到 ES5

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true
  }
}
1
2
3
4
5
6
7
8
9
10

修改webpack.config.js

webpack的入口起点指定为./index.ts,然后通过ts-loader加载所有的.ts.tsx文件,并且在当前目录输出一个bundle.js文件

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

这样我们就完成了对 TypeScript 的支持。

# 分包

接下来利用webpack多入口的属性来实现分包功能。先模拟工作路径创建一些ts文件来尝试分包。

  webpack-demo
  |- package.json
  |- tsconfig.json
  |- webpack.config.js
  |- /bin
    |- index.html
  |- /src
    |- main.ts
    |- com
       |- print.ts
  |- /minggame
    |- src
      |- minggame.ts
      |- com
        |- print.st
  |- /node_modules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

index.html

<!doctype html>
<html>

<head>
    <title>Ming-cli</title>
</head>

<body>
    <script src="./main.js"></script>
</body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12

完成工作路径的搭建之后,我们开始修改webpack.config.js,将入口设置为多个入口文件,并将它们分开js打包,并以不同的名称命名。在这里我们为了查看打包后的js文件是否正确,需要设置modedevelopment解除代码压缩,最新的webpack是默认用UglifyJsPlugin压缩代码的。

const path = require('path');

module.exports = {
    entry: {
        main: './src/main.ts',
        minggame: "./minggame/src/minggame.ts"
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'bin')
    },
      mode: 'development'
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 断点调试

webpack打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。为了更容易地追踪错误和警告,JavaScript提供了 source map功能,将编译后的代码映射回原始源代码。

这时候我们需要修改webpack.config.js文件,使用inline-source-map选项。

const path = require('path');

module.exports = {
    entry: {
        main: './src/main.ts',
        minggame: "./minggame/src/minggame.ts"
    },
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'bin')
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 重新加载

每次都去重新编译刷新浏览器很影响我们的工作效率,所以webpack-dev-server为我们提供了一个简单的web服务器,并且能够实时重新加载(live reloading)。

npm install --save-dev webpack-dev-server
1

修改webpack.config.js设置入口

const path = require('path');

module.exports = {
    entry: {
        main: './src/main.ts',
        minggame: "./minggame/src/minggame.ts"
    },
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist'
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'bin')
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

然后我们在package.json中增加一个脚本直接打开开发服务器。

{
  "name": "Ming-cli",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --open",
    "build": "webpack"
  },
  "keywords": [],
  "author": "zenosLin",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^5.3.1",
    "typescript": "^3.2.2",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.14"
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22