使用 webpack2 和 devServer

1,519 阅读1分钟

现如今web前端工程化越来越重要,如果不掌握不夸张的说连正常开发都进行不下去了。webpack现在已经成为了前端打包工具的标准了,那么掌握webpack对于一个FE来必不可少的。

目前正在学习rxjs,觉得它真的很酷,而且在实际项目开发也发现了几个应用场景,因此正值放假就想着用ts写写rx。

那么开始把~

项目地址

bulldog478/typscript-rx-seed

知识点

  • ts支持rx构建
  • html-webpack-plugin
  • devServer

过程

首先做好依赖包的安装工作,请看package.json

{
  "name": "hello",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "rxjs": "^5.2.1-smooth"
  },
  "devDependencies": {
    "awesome-typescript-loader": "^3.1.2",
    "html-webpack-plugin": "^2.28.0",
    "typescript": "^2.2.2",
    "webpack": "^2.3.2"
  }
}

这里没啥可说的,想用ts搞rxjs这些是最基本的依赖了。下面配置webpack.config.js

module.exports = {
    context: __dirname + "/src",
    entry: './index.ts',
    output: {
        filename: '[name].bundle.js',
        path: __dirname + '/dist',
        publicPath: '/dist'
    },
    module: {
        rules: [{
            test: /\.ts$/,
            use: 'awesome-typescript-loader'
        }]
    },
    resolve: {
        extensions: ['.ts', '.js']
    },

    devtool: 'source-map',
}

下面在index.ts中编写一个简单的rx测试程序

import { Observable } from 'rxjs'

var test$ = Observable.interval(1000)
test$.subscribe(x=>console.log('x', x))

下面我们先编译一下代码

webpack

会报一个`类型引用`无法找到的错误,


ERROR in [at-loader] ./node_modules/rxjs/operator/toPromise.d.ts:3:79

TS2693: 'Promise' only refers to a type, but is being used as a value here.


作者:诗瑶
链接:Typescript报错拾记 - 知乎专栏

应该是缺少Promise定义文件了,所以在tsconfig.json中的compilerOptions.lib加入es2015.promise即可
{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "removeComments": true,
        "typeRoots": [
            "./node_modules/@types"
        ],
        "lib": [
            "dom",
            "es2015",
            "scripthost",
            "es2015.promise"
        ]
    },
    "include": [
        "./src/**/*"
    ],
    "exclude": [
        "node_modules"
    ]
}
下面在src中编写首页index.html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
  </body>
</html>
有首页当然会想到html-webpack-plugin了,在webpack.config.js中加入配置
{
    plugins: [new HtmlWebpackPlugin({
        title: 'Hello RxJS',
        filename: __dirname + '/index.html',
        template: './index.html',
        inject: 'body'
    })]
}
再次执行命令行webpack,一切OK,在src同级目录下你会发现多出一个index.html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title>Hello RxJS</title>
  </head>
  <body>
  <script type="text/javascript" src="/dist/main.bundle.js"></script></body>
</html>
这个时候你可以通过lite-server或者其他任何可以启动web容器的工具来查看运行结果,这里我们开始说devServer,devServer通过webpack-dev-server.filesystem保存了通过webpack-dev-server执行编译的结果,因此它不会在你的目录看到任何输出文件,因此html-webpack-plugin所输出的index.html也驻留在了内存中,当你打开localhost:<port>时你会发现找不到index.html就是这个原因了,网上也有一些办法,但是我觉得没必要这个时间,因此我的办法就是先执行`webpack -w`保证index.html的输出,再执行`webpack-dev-server --inline --hot`来实现hot load,下面把完整的webpack.config.js贴上
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    context: __dirname + "/src",
    entry: './index.ts',
    output: {
        filename: '[name].bundle.js',
        path: __dirname + '/dist',
        publicPath: '/dist'
    },
    module: {
        rules: [{
            test: /\.ts$/,
            use: 'awesome-typescript-loader'
        }]
    },
    resolve: {
        extensions: ['.ts', '.js']
    },

    devtool: 'source-map',

    plugins: [new HtmlWebpackPlugin({
        title: 'Hello RxJS',
        filename: __dirname + '/index.html',
        template: './index.html',
        inject: 'body'
    })],

    devServer: {
        contentBase: __dirname,
        port: 9001,
        publicPath: '/dist',
        filename: '[name].bundle.js',
        watchContentBase: true,
        watchOptions: {
            aggregateTimeout: 300,
            poll: 1000
        }
    }
}

运行结果

修改代码,ctrl+s,程序reload

参考

开发中 Server(DevServer)

DevServer

热加载失败原因