前言
我们前面从前端架构:
- 前端框架系列之(装饰器Decorator)
- 前端框架系列之(vue-class-component)
- 前端框架系列之(vue-property-decorator)
- 前端框架系列之(mvc)
- 前端框架系列之(mvp)
- 前端框架系列之(mvvm)
到项目工程化工具eslint、babel、webpack等,分别结合demo跟源码做了具体的分析:
接下来我们把前面的所有知识点来实战一下,就当成前面所有知识点的一个总结了。
需求
我们都知道,当我们用react开发一个项目的时候,我们可以用官方的脚手架Create React App,当我们用vue开发一个项目的时候,我们也可以用官方的脚手架vue-cli, 用起来是真的爽啊!也不需要自己去配置eslint、babel、webpack等等,脚手架会根据你的选择自动帮你完成配置,是的! 一般项目都可以覆盖到,但是如果想要用好这些脚手架的话我们还是需要了解其中的一些配置的原理的。
我们这一次实战demo的需求是这样的:
- js框架(vue、typescript、tsx、jsx)
- css样式(sass)
- 工程化工具(eslint、babel、webpack、webpack-chain)
ok!这差不多算是一个比较复杂的项目了,接下来我们一步步来实现一下它。
开始
我们直接创建一个项目叫webpack-vue-demo,然后进到项目根目录执行npm init:
webpack-vue-demo npm init
...
Is this OK? (yes)
➜ webpack-vue-demo
webpack脚手架
创建完毕后,我们首先安装webpack相关依赖:
webpack(webpack框架)
yarn add -D webpack || npm install -D webpack
webpack-cli(webpack脚手架)
yarn add -D webpack-cli || npm install -D webpack-cli
webpack-dev-server(webpack开发环境)
yarn add -D webpack-dev-server || npm install -D webpack-dev-server
webpack-chain(webpack链式配置)
yarn add -D webpack-chain || npm install -D webpack-chain
ok! webpack脚手架相关的依赖我们算是安装完了,然后我们在工程根目录底下创建一个webpack配置文件webpack.config.js
,用webpack-chain
导出一个配置:
const config = new (require("webpack-chain"))();
module.exports = config.toConfig();
然后我们就可以在根目录执行npx webpack
跟npx webpack-dev-server
命令了,为了方便,我们直接在package.json
中声明两个脚本build
跟dev
,
{
"name": "webpack-vue-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist && webpack --mode=production",
"dev": "webpack-dev-server --mode=development --progress"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.44.0",
"webpack-chain": "^6.5.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}
我们试着运行一下build
命令:
> webpack-vue-demo@1.0.0 build xx/webpack/webpack-vue-demo
> rimraf dist && webpack --mode=production
Insufficient number of arguments or no entry found.
Alternatively, run 'webpack(-cli) --help' for usage info.
Hash: a8dc1c75fbec1af4c624
Version: webpack 4.44.0
Time: 29ms
Built at: 07/27/2020 4:45:12 PM
ERROR in Entry module not found: Error: Can't resolve './src' in 'xxx/webpack/webpack-vue-demo'
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! webpack-vue-demo@1.0.0 build: `rimraf dist && webpack --mode=production`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the webpack-vue-demo@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
➜ webpack-vue-demo git:(master) ✗
可以看到,webpack
直接报错了~ ok! 原因我就不解释了,没看过前面文章的童鞋强烈建议先看完再过来实战。
typescript
因为我们需求中需要支持ts,所以我们继续安装ts相关依赖:
typescript(ts脚手架)
yarn add -D typescript || npm install -D typescript
ts-loader(ts加载器)
yarn add -D ts-loader || npm install -D ts-loader
ok! ts相关依赖安装完毕后,我们可以开始创建我们项目的目录了,我们直接在根目录底下创建一个src目录,然后在src目录下创建一个main.ts
空文件当成项目的入口文件:
webpack-vue-demo
node_modules
src
main.ts
.gitignore
package.json
README.md
webpack.config.js
然后我们去修改一下webpack的配置。
入口配置
webpack.config.js:
const path = require("path");
const config = new (require("webpack-chain"))();
config
.context(path.resolve(__dirname, ".")) //webpack上下文目录为项目根目录
.entry("app") //入口文件名称为app
.add("./src/main.ts") //入口文件为./src/main.ts
.end()
.output
.path(path.join(__dirname,"./dist")) //webpack输出的目录为根目录的dist目录
.filename( "[name].[contenthash:8].js") //打包出来的bundle名称为[name].[contenthash:8].js
.publicPath("./") //publicpath配置为"./"
.end()
module.exports = config.toConfig();
我们再次执行npm run build
:
➜ webpack-vue-demo git:(master) ✗ npm run build
> webpack-vue-demo@1.0.0 build xxx/webpack/webpack-vue-demo
> rimraf dist && webpack --mode=production
Hash: f102af84da880d301fb5
Version: webpack 4.44.0
Time: 198ms
Built at: 07/27/2020 5:05:26 PM
Asset Size Chunks Chunk Names
app.995b67bc.js 964 bytes 0 [emitted] [immutable] app
Entrypoint app = app.995b67bc.js
[0] multi ./src/main.ts 28 bytes {
0} [built]
[1] ./src/main.ts 0 bytes {
0} [built]
➜ webpack-vue-demo git:(master) ✗
ok,这一次我们可以看到,webpack通过我们配置的入口文件main.ts文件打包出来了一个叫app.995b67bc.js的文件,
dist/app.995b67bc.js:
!function (e) {
var t = {
};
function n(r) {
if (t[r]) return t[r].exports;
var o = t[r] = {
i: r, l: !1, exports: {
}};
return e[r].call(o.exports, o, o.exports, n), o.l = !0, o.exports
}
n.m = e, n.c = t, n.d = function (e, t, r) {
n.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0, get: r})
}, n.r = function (e) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: