系統(tǒng)參數:
MacOS 10.12.6
Node.js: v8.2.1
yarn: 1.3.2
摘要
本文介紹:
- 如何安裝 React 項目啟動的前置依賴:Node.js 與 yarn
- React 項目腳手架的結構
- 三大主要文件的講解:package.json, webpack.config.js, .babelrc
項目代碼地址:React拾遺:項目腳手架
如何使用腳手架
1 安裝 Node.js
兩種方法安裝:
- 官網下載對應平臺的 Node.js 安裝包,然后直接安裝。
- 使用 Node 版本控制器(即,NVM,全稱 Node Version Manager)安裝 Node.js
NVM 的好處是可以同時安裝多個任意版本的 Node.js,而且每個版本之間的全局安裝包相互不會影響。
下面介紹在 MacOS 平臺下,NVM 的安裝和簡單使用方法。NVM 的詳細使用方法可以參考 node版本控制工具nvm。
安裝 NVM
在命令行輸入。(MacOS 如果沒有自帶 curl 命令,則可能需要先安裝 Xcode Command Line Tools)
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
繼續(xù)在命令行中,安裝指定版本的 Node.js。比如這里安裝 Node.js 8.2.1 版本。
NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node nvm install 8.2.1
確認安裝成功:
用 NVM 查看當前 Node.js 版本。
> nvm ls
-> v8.2.1
default -> 8.2.1 (-> v8.2.1)
用 node 命令查看版本號
> node -v
v8.2.1
查看 Node.js 安裝位置。(這個位置在配置 Sublime JsPrettier 時有用)
> which node
/Users/mac/.nvm/versions/node/v8.2.1/bin/node
更換國內淘寶源
因為眾所周知的原因,把 npm 的源更換成國內的源,各種 npm 包的安裝速度更快。更換國內源的方法參考文章:解決 npm install electron 卡在 node install.js 的問題。
具體操作是:
進入并編輯 npm 的配置文件: .npmrc:
vim ~/.npmrc
編輯內容,修改為以下內容,就能保證 npm 是從國內淘寶源進行安裝。
registry=https://registry.npm.taobao.org
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
electron_mirror="https://npm.taobao.org/mirrors/electron/"
2 全局安裝 yarn
在命令行輸入,建議指定版本 1.3.2。(本項目內的包安裝,盡量指定版本,確保結果一致)。
npm install -g yarn@1.3.2
yarn 的使用參考:JavaScript 包管理工具 yarn 的使用
3 安裝項目 npm 包
進入項目所在的目錄,
cd React-Perls
然后用 yarn 安裝
yarn install
4 啟動項目
1 測試服務器 webpack-dev-server 方式
在項目目錄下,用命令行輸入(該命令實際是運行 package.json 里面的腳本命令,可以自己編寫)
yarn run dev-server
命令行提示:項目運行在 http://localhost:8080/ (或者其他端口)。
...
Project is running at http://localhost:8080/
在瀏覽器中訪問該地址,即可顯示本項目的歡迎頁面:
React Project Scaffold
Welcome to React world!
2 webpack 打包后訪問
yarn build
打開項目中的 public 目錄中的 index.html 即可。
項目腳手架目錄
目錄結構如下
.
├── .babelrc
├── .gitignore
├── node_modules
├── package.json
├── public
├── src
│ ├── App.js
│ ├── index.js
│ └── template.html
├── webpack.config.js
└── yarn.lock
第一層有3個目錄
-
node_modules: npm 包文件目錄,所有通過 npm install 或者 yarn add 安裝的包,都在這個目錄下。 -
public: webpack 打包輸出目錄 -
src: source 文件夾,存放代碼的位置。其中 index.js 是入口 js 文件,template.html 是 html 模板文件,用于 webpack 打包輸出 index.html。
另外項目中最主要的三個文件:
-
package.json: npm 包管理文件,控制包的版本,另外里面有 scripts 命令行腳本命令,可以設置打包、啟動測試服務器、刪除 webpack 輸出文件夾等命令。 -
.babelrc:配置 babel 的編譯規(guī)則。 -
webpack.config.js:webpack 配置文件,設置輸入、輸出、loader 預處理,plugins 額外處理等內容。
package.json
主要用于控制 npm 包版本,以及編寫 scripts 腳本命令。
完整的依賴管理文件 package.json 如下
{
"name": "myProject",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"clean": "rimraf public",
"build": "yarn run clean && webpack",
"dev-server": "webpack-dev-server"
},
"devDependencies": {
"autoprefixer": "7.1.5",
"babel-core": "6.26.0",
"babel-loader": "7.1.2",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-preset-env": "1.6.0",
"babel-preset-react": "6.24.1",
"css-loader": "0.28.7",
"file-loader": "1.1.5",
"html-webpack-plugin": "2.30.1",
"postcss-loader": "2.0.7",
"rimraf": "2.6.2",
"style-loader": "0.19.0",
"url-loader": "0.6.2",
"webpack": "3.6.0",
"webpack-dev-server": "2.9.1"
},
"dependencies": {
"react": "16.0.0",
"react-dom": "16.0.0"
}
}
用 npm 完全沒有問題,只是這里采用了 yarn 而不是 npm,所以這里 scripts 中使用 yarn run 命令。
有了這個 package.json 以后,可以直接 yarn install 就能把對應版本的包安裝到 node_modules 目錄下。(前提是已經通過 sudo npm install -g yarn 全局安裝了 yarn)
1 React 依賴包
"react": "16.0.0",
"react-dom": "16.0.0"
生產和開發(fā)環(huán)境都需要使用的 react 以及 react-dom,這里采用了最新的 React 16 版本。后面還會安裝 react-redux, react-router-dom, redux-thunk 等。
2 Webpack 依賴包
"webpack": "3.6.0",
"webpack-dev-server": "2.9.1"
其中 webpack 是前端工程化經常使用的工具,而 webpack-dev-server 是開發(fā)測試服務器,兼具自動重新打包功能。
3 Babel 系列依賴包
全部放在開發(fā)依賴 devDependencies 部分
"babel-core": "6.26.0",
"babel-loader": "7.1.2",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-preset-env": "1.6.0",
"babel-preset-react": "6.24.1",
"babel-loader": "7.1.2"
Babel 針對 Webpack 做的 loader,可以結合 webpack 對 js 或者 jsx 文件進行預處理。"babel-core": "6.26.0"
Babel 的核心編譯包,但是不包含編譯規(guī)則(編譯集 preset)。"babel-preset-env": "1.6.0"
包括 es2015, es2016, es2017 等所有內容,不需要單獨安裝es2015 的包,在 npm 或者 yarn 安裝時會有提示。"babel-preset-react": "6.24.1"
React JSX 語法的編譯規(guī)則。"babel-plugin-transform-class-properties": "6.24.1"
babel 插件,增加 ES 7 中類的新屬性。由于該新語法正在起草,所以暫時放在 babel 插件中。據悉也可以使用 stage2,也有同樣效果。關于類的新屬性,后面有舉例講解。"babel-plugin-transform-object-rest-spread": "6.26.0"
spread 語法的 babel 插件。
4 Webpack 的 css 處理 loader
兩個包可以實現 css 的模塊化,把 css 打包進 js 文件中。如果需要把 css 單獨打包出來,需要使用 extract-text-webpack-plugin
"css-loader": "0.28.7",
"style-loader": "0.19.0",
5 Webpack 的 postcss 處理 loader
主要使用 autoprefixer,這樣可以正常寫 css,而 postcss 的 autoprefiexer 功能可以自動加上各種瀏覽器的前綴,特別是動畫效果部分的 css。
"autoprefixer": "7.1.5",
"postcss-loader": "2.0.7",
6 Webpack 的圖片處理 loader
主要是 url-loader,而 file-loader 是前者的依賴。
"file-loader": "1.1.5",
"url-loader": "0.6.2",
.babelrc
完整的 babel 配置文件 .babelrc 如下
{
"presets": ["env", "react"],
"plugins": ["transform-class-properties", "transform-object-rest-spread"]
}
.babelrc 是 babel 的配置文件。有些項目的配置喜歡把 babel 的配置放在 webpack 里面 babel-loader 下面的 query 中。建議單獨放在 .babelrc 文件進行配置。
- env: 包含了目前截至 es2017 的 babel 包。不用單獨去安裝 es2015,如果單獨安裝,npm 或者 yarn 都會提示可以直接安裝 babel-preset-env。
- react: 編譯jsx用
- transform-class-properties: es7語法,解決類中函數沒有綁定 this 的問題。使用了這個插件以后,可以使用ES 7中的新類的方法。
// 舊類函數要綁定this,而且類屬性放在構造方法constructor
class OldClass {
constructor() {
this.name = 'Jim';
this.printName = this.printName.bind(this);
}
printName () {
console.log(this.name);
}
}
const oldClass = new OldClass();
const oldPrintName = oldClass.printName;
oldPrintName();
// 新類屬性可以直接放在構造方法外,新類函數用箭頭函數就可以不用綁定this
class NewClass {
name = 'Jim';
printName = () => {
console.log(this.name);
}
}
const newClass = new NewClass();
const newPrintName = newClass.printName;
newPrintName();
- transform-object-rest-spread: 是需要使用解析方法
{...variable}以及[...variable]。
webpack.config.js
- 不常更改的公用js部分提取出放在 vendor 里面,而自己的 js 部分打包在 bundle.js,便于瀏覽器緩存,不用每次都發(fā)送一個很大的 js 文件。
- loader 處理 js, css, 以及圖片。
- css-loader 的options寫法,主要是把 css 進行模塊化,做成 scoped css,防止 css 在全局的命名沖突。
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
- postcss-loader 主要是用 autoprefixer 插件,可以給 css 自動加上 --webkit- 等瀏覽器前綴,對應瀏覽器是最近的兩個瀏覽器版本。
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
browsers: ['> 1%', 'last 2 versions']
})
]
}
- plugins 是把 js 和 css 注入到 template.html 最后變成 index.html 輸出。另外也把 vendor 的變化都放在 manifest 中。
完整的 webpack 配置文件 webpack.config.js 如下
const path = require('path');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require("webpack");
const VENDOR_LIBS = ["react", "lodash", "react-dom"];
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: {
bundle: './src/index.js',
vendor: VENDOR_LIBS
},
output: {
path: path.join(__dirname, 'public'),
filename: '[name].[chunkhash].js',
chunkFilename: '[id].js',
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({
browsers: ['> 1%', 'last 2 versions']
})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: 'url-loader?limit=8000&name=images/[name].[ext]'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + '/src/template.html',
filename: 'index.html',
inject: 'body'
}),
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'manifest']
})
],
devServer: {
contentBase: path.join(__dirname, 'public'),
historyApiFallback: true
}
};