Webpack+React+Typescript開發環境
Webpack
FaceBook的Instagram團隊開發的一個前端打包工具,比起之前的一些前端自動化構建工具,比如Gulp和Grunt來說,Webpack是基於依賴來進行代碼整合的。也就是必須要有一個入口檔案,這個入口檔案中會引入其他的指令檔,之後webpack通過這些依賴關係將所有的檔案打包,並且可以自動產生sourcemap來方便調試。 dependence 目錄結構
基本的開發環境首先需要安裝node、npm這些就不多說了,然後需要使用npm安裝webpack以及typescript。具體的使用方法可以參考兩個的官方文檔:
首先建立項目的目錄結構:
mkdir WebpackProjectcd WebpackProjectmkdir srcmkdir distcd srcmkdir 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-loadernpm link typescriptnpm 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官方的參考文檔。