Webpack+React+Typescript开发环境

Webpack+React+Typescript开发环境

Webpack

FaceBook的Instagram团队开发的一个前端打包工具,比起之前的一些前端自动化构建工具,比如Gulp和Grunt来说,Webpack是基于依赖来进行代码整合的。也就是必须要有一个入口文件,这个入口文件中会引入其他的脚本文件,之后webpack通过这些依赖关系将所有的文件打包,并且可以自动生成sourcemap来方便调试。

dependence

目录结构

基本的开发环境首先需要安装node、npm这些就不多说了,然后需要使用npm安装webpack以及typescript。具体的使用方法可以参考两个的官方文档:

首先建立项目的目录结构:

mkdir WebpackProject
cd WebpackProject
mkdir src
mkdir dist
cd src
mkdir components

得到如下的目录结构:

依赖安装

首先初始化npm

npm init

一路上看着填写就可以了,如果只是试验环境的话可以一路Enter下去。

安装webpack以及typescript:

npm install -g webpack typescript

现在国内的npm速度比较慢,可以使用阿里自己搭建的国内的npm镜像站:cnpm来进行依赖安装。

安装react相关的依赖:

npm install --save-dev react react-dom @types/react @types/react-dom

在构建开发环境的时候,需要一些webpack插件来协助完成代码打包,由于我们使用了typescript这种JavaScript的super set来进行开发,所以要安装webpack的typescript解析工具,并且在现在这种自动化构建工具构建的代码中,代码都是经过压缩或者打包的,也就是在错误提示的时候,根本不知道错误究竟出现在哪里,所以现在chrome支持了sourceMap来对代码进行定位,这里sourceMap就不具体解释了,有兴趣的同学可以自己上网搜索一下。

安装webpack的依赖工具:

npm install --save-dev ts-loader source-map-loader
npm link typescript
npm install --save-dev webpack-dev-server

这时所有的依赖都安装完了,现在可以根据自己的需求初始化一下git或者bower。

环境配置

在使用typescript的时候可以自己指定其一些配置:

tsc --init

通过上面的命令生成typescript的配置文件:tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "files": [
        "./src/components/Hello.tsx",
        "./src/index.tsx"
    ]
}

看到files数组里面我们放了两个文件,这两个文件中index.tsx作为入口文件,Hello.tsx文件作为引入的内容:

index.tsx

import * as React from "react";
import * as ReactDOM from "react-dom";

import { Hello } from "./components/Hello";

ReactDOM.render(
    <Hello compiler="TypeScript" framework="React" />,
    document.getElementById("example")
);

Hello.tsx

import * as React from "react";

export interface HelloProps { compiler: string; framework: string; }

export class Hello extends React.Component<HelloProps, {}> {
    render() {
        return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>;
    }
}

然后配置webpack的配置文件:

webpack.config.js

var path = require("path");
module.exports = {
    //入口文件的路径
    entry: "./src/index.tsx",
    output: {
      //打包的输出路径
        path: path.resolve(__dirname,"dist"),
        filename: "bundle.js",

    },

    // 启用sourceMap
    devtool: "source-map",

    resolve: {
        // 添加需要解析的文件格式
        extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
    },
    //加载的模块,这里包括ts和source-map
    module: {
        loaders: [

            { test: /\.tsx?$/, loader: "ts-loader" }
        ],

        preLoaders: [

            { test: /\.js$/, loader: "source-map-loader" }
        ]
    }, 
    //webpack的本地服务器webpack-dev-server的配置
    devServer: {
        contentBase: "./",
        colors: true,
        historyApiFallback: true,
        inline: true
    },


    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    },
};

在工程根目录中添加一个index.html的html文件,来引入webpack生成的打包好的文件:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
</head>

<body>
    <div id="example"></div>

    <!-- Dependencies -->
    <script src="http://localhost:8080/webpack-dev-server.js"></script>
    <script src="./node_modules/react/dist/react.js"></script>
    <script src="./node_modules/react-dom/dist/react-dom.js"></script>

    <!-- Main -->
    <script src="./dist/bundle.js"></script>
</body>

</html>

验证

在根目录下面运行:

webapck

可以看到生成了一个bundle.js文件为打包好的脚本文件:

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;
/******/
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.loaded = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    var React = __webpack_require__(1);
    var ReactDOM = __webpack_require__(2);
    var Hello_1 = __webpack_require__(3);
    ReactDOM.render(React.createElement(Hello_1.Hello, {compiler: "TypeScript", framework: "React"}), document.getElementById("example"));


/***/ },
/* 1 */
/***/ function(module, exports) {

    module.exports = React;

/***/ },
/* 2 */
/***/ function(module, exports) {

    module.exports = ReactDOM;

/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    var __extends = (this && this.__extends) || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
    var React = __webpack_require__(1);
    var Hello = (function (_super) {
        __extends(Hello, _super);
        function Hello() {
            _super.apply(this, arguments);
        }
        Hello.prototype.render = function () {
            return React.createElement("h1", null, 
                "Hello from ", 
                this.props.compiler, 
                " and ", 
                this.props.framework, 
                "!");
        };
        return Hello;
    }(React.Component));
    exports.Hello = Hello;


/***/ }
/******/ ]);
//# sourceMappingURL=bundle.js.map

也会生成指定的sourceMap文件。

如果运行:

webpack-dev-server --inline

可以通过访问localhost:8080来访问这个工程。并且支持冷刷新,也就是更新一个文件之后,会刷新整个项目的所有内容,也可以通过修改webpack的配置来支持热刷新,只更新其中对应模块的代码。

其他有关webpack的内容具体可以参考webpack官方的参考文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值