想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!css
在過去的一年和一些人中,我一直在與 Creative Tim 合做。 我一直在使用 create-react-app 來開發一些不錯的產品。 有不少客戶詢問如何在 Webpack 上遷移咱們的產品模板。html
在屢次要求求以後,咱們寫了這個關於如何開始使用 React with Webpack 4和 Babel 7 的小教程。在本教程的最後,將向你們展現如何在新建立的應用程序上添加 Material Dashboard React。前端
在咱們開始以前,請確保你的電腦上安裝了 npm 和 Nodejs 的最新版本。在撰寫本文時,個人電腦上的最新版本是 npm 的 6.4.1
和 Nodejs 的 8.12.0
(lts)。node
首先,建立工程目錄:react
mkdir react-webpack-babel-tutorial cd react-webpack-babel-tutorial
如今咱們已經建立了咱們要開發應用程序的文件夾,接着須要添加一個 package.json
文件。 有兩種建立方式,你能夠選擇其中的一種:webpack
1.只需建立 package.json 文件,無需任何其餘配置:git
npm init -y
以下所示,package.json 文件已建立,其中包含一些很是基本的信息。github
2.使用一些額外的配置設置建立 package.json 文件web
npm init
我在咱們新建立的 package.json 文件中添加了一些東西,好比一些很好的 keywords,一個repo等等...npm
以後,在根目錄下建立 src 文件夾,而後在 src 下分別建立 index.html
和 index.js
.
1.Linux / MacOS 命令
mkdir src touch src/index.html touch src/index.js
2.Windows 命令
mkdir src echo "" > src\index.html echo "" > src\index.js
建立完後在 index.html 添加如下內容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="theme-color" content="#000000"> <title>React Tutorial</title> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. --> </body> </html>
接着在 index.js 中添加一些內容,目前只是爲了展現一些內容,下面繼續完善。
(function () { console.log("hey mister"); }());
此時,目錄結構以下:
安裝 Webapck 及所需的開發環境依賴模塊。
npm install --save-dev webpack webpack-cli webpack-dev-server
看一下package.json文件,將看到這三個包被添加到這個文件中,以下所示:
"devDependencies": { "webpack": "^4.19.0", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.8" }
補充說明一下版本號前的 ^,~ 的區別
~
指定版本:好比 "webpack-cl": "~3.1.0",表示安裝 3.1.0
的最新版本(不低於1.1.0),可是不安裝 1.2.x
,也就是說安裝時不改變大版本號和次要版本號^
指定版本:好比 "webpack-dev-server": "^3.1.8",,表示安裝 請輸入代碼
3.1.4 及以上的版本,可是不安裝4.0.0,也就是說安裝時不改變大版本號。package.json
文件只能鎖定大版本,也就是版本號的第一位,並不能鎖定後面的小版本,你每次 npm install
都是拉取的該大版本下的最新的版本,爲了穩定性考慮咱們幾乎是不敢隨意升級依賴包的,這將致使多出來不少工做量,測試/適配等,因此 package-lock.json
文件出來了,當你每次安裝一個依賴的時候就鎖定在你安裝的這個版本。
因此當咱們 npm install
安裝完插件後,都會生成兩個文件一個是 node_modules 和 package-lock.json 。
這裏爲了版本的一致性,我把 package.json 裏的 版本號前面 ^
刪除了。
接着新建 Webpack 配置文件 webpack.config.js:
1.Linux/MacOS 命令
touch webpack.config.js
2.Windows 命令
echo "" > webpack.config.js
若是你不想使用命令行,也能夠簡單地手動建立文件。
在開始處理 Webpack 配置文件以前,先在應用程序中安裝一些咱們須要的東西。
首先安裝 path 做爲開發環境的路徑依賴。
npm install --save-dev path
此外,因爲不想在 HTML 中手動注入 index.js 文件,所以須要安裝 html-webpack-plugin 的插件。 此插件經過配置在 HTML 文件中注入 index.js,無需手動操做。
npm install --save-dev html-webpack-plugin
再次,我將 package.json 文件刪除全部 ^
。
安裝完後在 package.json 文件中的 scripts 屬性裏添加覺得內容:
"webpack": "webpack", "start": "webpack-dev-server --open"
如今 package.json 內容以下:
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack", "start": "webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim <hello@creative-tim.com> (https://www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "html-webpack-plugin": "3.2.0", "path": "0.12.7", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" } }
接着運行如下命令,看看會發生什麼:
npm run webpack
Webpack 將自動獲取 src/index.js 文件,編譯它,並將其輸出到 dist/main.js 中,並壓縮代碼。這是由於咱們尚未配置 Webpack 配置文件。此外,因爲咱們尚未配置該文件,我控制檯中將出現一些警告。
若是咱們運行以下命令:
npm start
webpack-dev-server 將自動啓動服務器並使用該服務器打開默認瀏覽器。可是,因爲咱們沒有配置webpack.config.js 文件,因此頁面展現並非咱們想要的內容。
若是想中止服務,只需在命令行中同時按下 CTRL + C 鍵。
接着在 webpack.config.js 添加如下內容:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: path.join(__dirname,'src','index.js'), output: { path: path.join(__dirname,'build'), filename: 'index.bundle.js' }, mode: process.env.NODE_ENV || 'development', resolve: { modules: [path.resolve(__dirname, 'src'), 'node_modules'] }, devServer: { contentBase: path.join(__dirname,'src') }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname,'src','index.html') }) ] };
entry 能夠是個字符串或數組或者是對象。 當 entry 是個字符串的時候,用來定義入口文件:
entry: './js/main.js'
當 entry 是個數組的時候,裏面一樣包含入口js文件,另一個參數能夠是用來配置webpack提供的一個靜態資源服務器,webpack-dev-server。webpack-dev-server 會監控項目中每個文件的變化,實時的進行構建,而且自動刷新頁面:
entry: [ 'webpack/hot/only-dev-server', './js/app.js' ]
當 entry 是個對象的時候,咱們能夠將不一樣的文件構建成不一樣的文件,按需使用,好比在個人 hello 頁面中只要\
引入 hello.js 便可:
entry: { hello: './js/hello.js', form: './js/form.js' }
output 參數是個對象,用於定義構建後的文件的輸出。其中包含 path 和 filename:
output: { path: './build', filename: 'bundle.js' }
這是輸出的模式,這裏將其 mode 設置爲 「development」。若是在腳本中指定 NODE_ENV 變量,那麼它將使用這個變量。請參閱下面關於如何使用 NODE_ENV 的示例(請注意,本教程中的 package.json 文件中不會進行如下更改,這只是一個示例,能夠看到它是如何工做的)
"webpack": "NODE_ENV=production webpack",
webpack 在構建包的時候會按目錄的進行文件的查找,resolve 屬性中的 extensions
數組中用於配置程序能夠自行補全哪些文件後綴:
resolve:{ extensions:['','.js','.json'] }
這告訴 webpack-dev-server 須要提供哪些文件。 這裏是 src
文件夾中的全部內容都須要在瀏覽器中瀏覽。
在這裏,咱們設置了咱們的應用程序中須要的插件。到目前爲止,只須要 html-webpack-plugin,它告訴服務器 index.bundl.js 應該被注入到 index.html 文件中
再次運行如下命令,顯示會跟上一次不一樣:
npm run webpack
webpack-dev-server 從 src 文件夾中讀取全部內容並輸出到咱們的瀏覽器中。
經過運行如下命令來引入 React :
npm i react react-dom --save-dev
在咱們的開發過程當中,若是咱們在 JS 文件中添加React代碼,Webpack 會給咱們一個錯誤,它不知道如何在bundle.js 文件中編譯 React。
修改 index.js 內容以下:
import React from "react"; import ReactDOM from "react-dom"; let HelloWorld = () => { return <h1>Hello there World!</h1> } ReactDOM.render( <HelloWorld/>, document.getElementById("root") );
再次運行如下命令:
npm start
錯誤以下:
因此這就是 Babel 出現的緣由, Babel 將告訴 Webpack 如何編譯 React 代碼。
安裝 Babel 相關依賴:
npm install --save-dev @babel/core @babel/node @babel/preset-env @babel/preset-react babel-loader
這是將ES6及以上版本編譯成ES5
babel-node
是 babel-cli
的一部分,它不須要單獨安裝。
它的做用是在 node 環境中,直接運行 es2015 的代碼,而不須要額外進行轉碼。例如咱們有一個 js 文件以 es2015 的語法進行編寫(如使用了箭頭函數)。咱們能夠直接使用 babel-node es2015.js
進行執行,而不用再進行轉碼了。
能夠說:babel-node = babel-polyfill + babel-register
這個是把 React 代碼編譯成 ES5 代碼。
和 babel-cli
同樣,babel-loader 也會讀取 .babelrc
或者 package.json
中的 babel
段做爲本身的配置,以後的內核處理也是相同。惟一比 babel-cli
複雜的是,它須要和 webpack 交互,所以須要在 webpack 這邊進行配置。比較常見的以下:
module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, loader: 'babel-loader' } ] }
若是想在這裏傳入 babel
的配置項,也能夠把改爲:
// loader: 'babel-loader' 改爲以下: use: { loader: 'babel-loader', options: { // 配置項在這裏 } }
咱們須要爲項目中添加一些樣式,此時就須要使用樣式相關的加載器,這邊使用 scss
,安裝命令以下:
npm install --save-dev style-loader css-loader sass-loader node-sass
經過注入 <style>
標籤將 CSS 添加到 DOM 中
css-loader用於將 css 文件打包到js中, 經常配合 style-loader 一塊兒使用,將 css 文件打包並插入到頁面中
加載 SASS/SCSS 文件
將 SCSS 文件編譯爲 CSS 文件
在 src 下建立 scss 文件:
1.Linux/MacOS 命令
touch src/index.scss
2.window 命令
echo "" > src/index.scss
並添加如下內容:
body { div#root{ background-color: #222; color: #8EE4AF; } }
接着導入 index.js 中
import React from "react"; import ReactDOM from "react-dom"; // this line is new // we now have some nice styles on our react app import "index.scss"; let HelloWorld = () => { return <h1>Hello there World!</h1> } ReactDOM.render( <HelloWorld/>, document.getElementById("root") );
記得刪除 package.json 中的 ^
號,內容以下:
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack", "start": "webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim <hello@creative-tim.com> (https://www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "@babel/core": "7.0.1", "@babel/node": "7.0.0", "@babel/preset-env": "7.0.0", "@babel/preset-react": "7.0.0", "babel-loader": "8.0.2", "css-loader": "1.0.0", "html-webpack-plugin": "3.2.0", "node-sass": "4.9.3", "path": "0.12.7", "sass-loader": "7.1.0", "style-loa der": "0.23.0", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" }, "dependencies": { "react": "16.5.1", "react-dom": "16.5.1" } }
若是咱們再次運行上述任何命令,錯誤仍將存在。 咱們尚未告訴 Webpack 它應該使用 Babel 和樣式加載器來編譯咱們的 React 和 SCSS 代碼。
接下來要作的是爲 Babel 添加配置文件。 爲此,須要建立一個名爲 .babelrc
的文件,用來配置 Babel。
能夠直接在 webpack.config.js 文件中添加 Babel 的配置。 爲此,你能夠查看官方的 babel-loader 文檔。 就我而言,我認爲最好將 Babel 配置放在本身的文件中,這樣就不會使 Webpack 配置過於複雜難讀。
在根目錄下建立 .babelrc
1.Linux/MacOS 命令
touch .babelrc
2.Windows 命令
echo "" > .babelrc
並在 .babelrc 中添加如下代碼,這樣 babel-loader 就會知道用什麼來編譯代碼:
{ "presets": [ "@babel/env", "@babel/react" ] }
完成這些步驟後,咱們須要在項目中添加一些內容,以便咱們能夠導入各類文件,如圖像。 還須要添加一個插件,讓咱們可使用類等等。 讓咱們在類中添加類屬性,基本上,它將讓咱們可以使用 面向對象編程 方式來編寫代碼。
所以,讓咱們將 webpack.config.js 更改成如下內容(我也添加了一些註釋,可能會對你有所幫助):
// old // const path = require('path'); // const HtmlWebpackPlugin = require('html-webpack-plugin'); // new import path from 'path'; import HtmlWebpackPlugin from 'html-webpack-plugin'; module.exports = { entry: path.join(__dirname,'src','index.js'), output: { path: path.join(__dirname,'build'), filename: 'index.bundle.js' }, mode: process.env.NODE_ENV || 'development', resolve: { modules: [path.resolve(__dirname, 'src'), 'node_modules'] }, devServer: { contentBase: path.join(__dirname,'src') }, module: { rules: [ { // 這樣咱們就能夠將React、ES6及以上的任何內容編譯成正常的ES5語法 test: /\.(js|jsx)$/, // 不但願編譯node_modules中的任何內容 exclude: /node_modules/, use: ['babel-loader'] }, { test: /\.(css|scss)$/, use: [ "style-loader", // creates style nodes from JS strings "css-loader", // translates CSS into CommonJS "sass-loader" // compiles Sass to CSS, using Node Sass by default ] }, { test: /\.(jpg|jpeg|png|gif|mp3|svg)$/, loaders: ['file-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname,'src','index.html') }) ] };
咱們須要對 package.json 文件作一個更改。咱們須要告訴咱們的腳本在 Webpack 的配置文件中,使用 import 而不是 require 語句。 不然它會給咱們一個錯誤,它不知道import 表示什麼。
{ "name": "react-webpack-babel-tutorial", "version": "1.0.0", "description": "This is a Tutorial to showcase the usage of React with Webpack and Babel", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "babel-node ./node_modules/webpack/bin/webpack", "start": "babel-node ./node_modules/webpack-dev-server/bin/webpack-dev-server --open" }, "repository": { "type": "git", "url": "git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git" }, "keywords": [ "react", "webpack", "babel", "creative-tim", "material-design" ], "author": "Creative Tim <hello@creative-tim.com> (https://www.creative-tim.com/)", "license": "MIT", "bugs": { "url": "https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues" }, "homepage": "https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme", "devDependencies": { "@babel/core": "7.0.1", "@babel/node": "7.0.0", "@babel/plugin-proposal-class-properties": "7.0.0", "@babel/preset-env": "7.0.0", "@babel/preset-react": "7.0.0", "babel-loader": "8.0.2", "css-loader": "1.0.0", "file-loader": "2.0.0", "html-webpack-plugin": "3.2.0", "node-sass": "4.9.3", "path": "0.12.7", "sass-loader": "7.1.0", "style-loader": "0.23.0", "webpack": "4.19.0", "webpack-cli": "3.1.0", "webpack-dev-server": "3.1.8" }, "dependencies": { "react": "16.5.1", "react-dom": "16.5.1" } }
咱們還須要在 .babelrc 文件中添加 @babel/plugin-proposal-class 屬性,Babel將會知道如何處理類屬性。
{ "presets": [ "@babel/env", "@babel/react" ], "plugins": [ "@babel/plugin-proposal-class-properties" ] }
如今總算配置完成了。再次運行上述任何一個命令,就能夠順利跑起來啦。
npm run webpack
npm start
正如在這篇文章的開頭講的,咱們不會講 Material Design 樣式如何寫,這須要大量的工做。
相反,這裏添加一個很好的產品來實現 Google 的 Material Design,其中包括Creative Tim 員工的一些小改動。 咱們將向其添加 Material Dashboard React。
首先從 github 上把項目拷貝下來:
git clone https://github.com/creativetimofficial/material-dashboard-react.git
好的,如今咱們有兩個項目 - Material Dashboard React 和 咱們剛建立的項目。
如今,咱們不能簡單地將 src 文件夾從 Material Dashboard React 複製到咱們的新項目中。 這會給咱們帶來不少錯誤, 如缺乏依賴關係的錯誤,找不到模塊等。
所以,我建議首先將 Material Dashboard React 的 package.json 中的依賴項添加到 package.json 中。 咱們不須要 Material Dashboard React 包中的全部依賴項,由於咱們使用 Webpack 構建了本身的服務器。 除了產品自己,咱們還添加了其餘樣式加載器。
因此說,咱們須要以下:
npm install --save @material-ui/core@3.1.0 @material-ui/icons@3.0.1 @types/googlemaps@3.30.11 @types/markerclustererplus@2.1.33 chartist@0.10.1 classnames@2.2.6 perfect-scrollbar@1.4.0 react-chartist@0.13.1 react-google-maps@9.4.5 react-router-dom@4.3.1 react-swipeable-views@0.12.15
咱們不會所有都講,你能夠在 npmjs.com 上找到它們的詳細信息和它們本身的文檔。
再一次,進入 package.json 文件並從咱們剛剛安裝的安裝包中刪除(^)
。
接着拷貝 Material Dashboard React src 下的全部文件到咱們項目 src 下
好了,差很少作完了,咱們拷貝 Material Dashboard React 下的 src文件中全部內容到咱們項目 src 下,並覆蓋 index.js 文件。可是要保留 index.html 文件。
拷貝前
拷貝後
如今須要在 index.html 中添加一些樣式和字體,以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="theme-color" content="#000000"> <link rel="stylesheet" href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css"> <script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <title>React Tutorial</title> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. --> </body> </html>
還有一個小問題。 當咱們刷新頁面時,有一個錯誤 Cannot GET/dashboard
。 若是咱們跳轉到另外一個頁面,會獲得如, Cannot GET /user
錯誤等 。 因此根本上,咱們的路由不起做用,須要在 src/index.js
或 webpack.config.js 中進行一些更改。
這裏選擇使用第一個方案,由於它很是簡單易懂。
咱們在新導航方式在 index.js 更改 history,使用 createHashHistory() 替換 createBrowserHistory()。
這將容許咱們刷新頁面而不會出現任何其餘錯誤,如今咱們完成了。
import React from "react"; import ReactDOM from "react-dom"; import { createHashHistory } from "history"; import { Router, Route, Switch } from "react-router-dom"; import "assets/css/material-dashboard-react.css?v=1.5.0"; import indexRoutes from "routes/index.jsx"; const hist = createHashHistory(); ReactDOM.render( <Router history={hist}> <Switch> {indexRoutes.map((prop, key) => { return <Route path={prop.path} component={prop.component} key={key} />; })} </Switch> </Router>, document.getElementById("root") );
原文:
https://medium.freecodecamp.o...
你的點贊是我持續分享好東西的動力,歡迎點贊!