摘要:的配置其中就不多說會(huì)解決更改組件的時(shí)熱更新直接刷新頁面的問題。
工欲善其事,必先利其器。單頁面應(yīng)用的開發(fā)和生產(chǎn)環(huán)境涉及文件的編譯、壓縮、打包、合并等,目前前端最流行的莫過于 webpack 。為了深入了解 webpack 以及其相關(guān)插件,我們決定不采用腳手架,自己來搭建基于 webpack 的開發(fā)和生產(chǎn)環(huán)境。
基礎(chǔ)環(huán)境nodejs的安裝: 移步官網(wǎng)
Webpack相關(guān)plugin、loader的介紹建議使用nvm來管理nodejs的版本
安裝nvm
我們使用的是 [email protected] ,建議讀完 官方文檔 對(duì)她有個(gè)大概的了解。
webpack-dev-server 用 webpack-dev-server 來進(jìn)行開發(fā)環(huán)境下面的自動(dòng)打包編譯,包括熱更新等等。當(dāng)然也可以自己通過 webpack-dev-middleware 來自定義一個(gè)開發(fā)服務(wù)器。具體可以參考 webpack-dev-server 的源代碼。
webpack-hot-middleware 向入口文件中添加一個(gè) client 文件,當(dāng)文件變化時(shí),服務(wù)器端可以通過 socket 事件來通知這個(gè) client 來實(shí)現(xiàn)熱更新。注:這個(gè)事件是 EventSource事件。 webpack-dev-server 已經(jīng)將這個(gè)中間件封裝到內(nèi)部,我們只需要進(jìn)行配置即可。
babel-loader 編譯 es6 代碼。移步官網(wǎng)。值得一提的是 es2016, es2017, env 等是對(duì)已經(jīng)或者將要被加入 JS這門語言的提案進(jìn)行預(yù)編譯,而 stage-0 , stage-1 , stage-2 等是對(duì)將來可能加入立案里面的語法的預(yù)編譯。
extract-text-webpack-plugin 樣式文件默認(rèn)會(huì)被 webpack 打包到j(luò)s文件中。這個(gè)插件可以提取出這些被打包進(jìn)入的文件。
當(dāng)然我們用到的不只是這些,你可以到npm官網(wǎng)或者github上面找到這些plugin、loader的詳細(xì)用法
初始目錄結(jié)構(gòu)blog ├─ dist # 輸出目錄 ├─ task # 這里來放webpack處理和配置文件 ├─ src | ├─ components # 組件 | └ index.js # 入口文件 | package.json跑通開發(fā)環(huán)境
在 src/ 目錄下新建入口文件 index.js
import React from "react" import ReactDOM from "react-dom" // 這里需要借助 webpack 的同名功能來代替繁瑣的相對(duì)路徑 import HomeComponent from "components/Home" ReactDOM.render(, document.getElementById("root"))
在 src/component/ 目錄下新建 Home.js 模塊
import React, { Component } from "react" export default class Home extends Component { render(){ returnHello world!} }
在 src/ 目錄下新建 index.html 文件來作為單頁面的HTML文件
blog
現(xiàn)在我們來添加 webpack 的配置文件來對(duì)這些文件進(jìn)行打包、編譯
在 task/ 目錄下新建 config.js 文件
const path = require("path") const webpack = require("webpack") const webpackMerge = require("webpack-merge") const HtmlWebpackPlugin = require("html-webpack-plugin") const base = { // 上下文環(huán)境,相對(duì)路徑都基于這個(gè)路徑 context: path.resolve(__dirname, ".."), entry: "./src/index.js", output: { path: path.resolve(__dirname, "../dist"), publicPath: "/assets/", filename: "[name].js" }, module: { rules: [ { test: /.js$/, include: path.resolve(__dirname, "../src"), exclude: [ /node_modules/ ], use: [ "react-hot-loader", { loader: "babel-loader", options: { presets: ["env", "react"], plugins: [ "add-module-exports", "transform-runtime" ] } } ], } ] }, resolve: { extensions: [".js", ".jsx"], alias: { // 這里對(duì)應(yīng)著入口文件中 component 的同名配置 components: path.resolve(__dirname, "../src/components") } } } const dev = webpackMerge(base, { output: { publicPath: "/" }, // 源文件的 source map devtool: "source-map", plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.DefinePlugin({ "process.env": { NODE_ENV: ""development"" } }), new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", inject: true }) ], devServer: { // 開啟熱加載,需要 hmr 的支持 hot: true, contentBase: path.resolve(__dirname, "../dist"), // 這個(gè)路徑一定要和 output 的 publicPath 的屬性一致 publicPath: "/", } }) const prod = webpackMerge(base, { }) // 根據(jù) NODE_ENV 來決定輸出的配置 module.exports = process.env.NODE_ENV === "production" ? prod : dev
在項(xiàng)目跟路徑下執(zhí)行
export NODE_ENV=development && webpack-dev-server --config ./task/config.js
export NODE_ENV=development 設(shè)置 NODE_ENV 這個(gè)環(huán)境變量為 development 有助于我們區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境。這是mac下面的設(shè)置方法,windows 可以自行搜索
編譯成功,并且頁面輸出 Hello world! 表示配置跑通...
在 package.json 添加
{ "scripts": { "dev": "export NODE_ENV=development && webpack-dev-server --config ./task/config.js --progress --colors --hotOnly" } }TROUBLESHOOTING 通過 webpack-merge 來覆蓋 output.publicPath 屬性
如果 devServer.publicPath = output.publicPath = "/assets/" 的話,那么在瀏覽器中打開 localhost:80XX/assets/index.html 才能訪問到 index.html 文件,而將 publicPath = "/" 就直接通過 localhost:80XX 就可以訪問。
loader 的配置其中 include, exclude 就不多說
{ use: [ "react-hot-loader", { loader: "babel-loader", options: { presets: ["env", "react"], plugins: [ "add-module-exports", "transform-runtime" ] } } ], }
react-hot-loader 會(huì)解決更改 react 組件的時(shí) webpack 熱更新直接刷新頁面的問題。
babel-presets-react 用來處理 react 的 jsx 語法
babel-plugin-add-module-exports babel@6 會(huì)將es6的語法
// home.js export default "foo"
轉(zhuǎn)化為
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = "foo";
所以在使用 commonjs 的語法 require("./home") 時(shí),得到的是
{default: "foo"} ,所以:
var home = require("./home").default console.log(home) // "foo"
這個(gè)插件可以避免這一現(xiàn)象
html-webpack-plugin這里解釋一下使用 html-webpack-plugin 的必要性。
其實(shí)完全可以扔一個(gè)靜態(tài)的 index.html 給 webpack-dev-server ,這里面只需要有個(gè) 標(biāo)簽,就可以成功來進(jìn)行訪問。但是更多的時(shí)候我們會(huì)定制打包文件的名稱: output.filename: "[name]-[hash].js" ,編譯之后 webpack 會(huì)輸出一個(gè)類似于這樣的文件 bundle-fb9758acf17b2b5fb653.js ,那么你每次打包都需要去更改那個(gè)src屬性,而 html-webpack-plugin 可以幫你解決這些事情
在 src/component/ 下新建 Home.module.less
@color: green; :global { body { background-color: red; } } .wrap { color: @color; }
在同級(jí)目錄下的 Home.js 組件中引入這個(gè) less 文件
import React, { Component } from "react" import Style from "./home.module.less" export default class Home extends Component { render(){ returnHello world!} }
我們沒有在 task/config.js 下增加對(duì) less 文件的支持,肯定會(huì)報(bào)錯(cuò)的。先說一下為什么要以 .module.less 標(biāo)識(shí) less 文件,只會(huì)我們會(huì)引入 babel-plugin-import 對(duì)樣式庫 antd 進(jìn)行按需加載,由于 antd 源代碼中的樣式文件也是用 less 寫的,這樣會(huì)導(dǎo)致這些文件被作為 css-module 處理,所以加以區(qū)別,這是參考 atool-build 的配置。
在 task/config.js 文件新增 :
const ExtractTextPlugin = require("extract-text-webpack-plugin") const autoprefixer = require("autoprefixer") const runsack = require("rucksack-css") const theme = require("../theme.js")() const postcssPlugins = () => [ runsack(), // 可選 autoprefixer({ browsers: ["last 2 versions", "Firefox ESR", "> 1%", "ie >= 8", "iOS >= 8", "Android >= 4"], }), ] // 在base.module.rules里增加 { test: /.module.less$/, loader: ExtractTextPlugin.extract({ fallback: "style-loader", // 將下面處理過的文件插入html中 use: [ { loader: "css-loader", // 開啟對(duì)css-module的支持,并定義className的輸出格式 options: { modules: true, importLoaders: 1, localIdentName: "[name]__[local]___[hash:base64:5]"} }, { loader: "postcss-loader", options: { plugins: postcssPlugins } }, { loader: "less-loader", // 覆蓋默認(rèn)的全局配置 options: {"modifyVars": theme} } ] }) }, // 在 base.plugins 里增加 new ExtractTextPlugin({ filename: "css/[name]-[hash].css", }),
其他的 loader 和 webpack plugin 就不再贅述, 移步文檔
還要注意的是 less-loader 中的配置選項(xiàng),{"modifyVars": theme} ,這可以覆蓋 less 文件的配置,可以用來自定義樣式庫 antd , 繼續(xù)查看
在項(xiàng)目根目錄下新建 theme.js
module.exports = function(){ return {} }
別忘記安裝配置文件里面用到的 loader、pulgins… = =
安裝 less-loader 記得把 less 也裝上,它的文檔也是有強(qiáng)調(diào)的哦!
基礎(chǔ)的環(huán)境配置就到這里。生產(chǎn)環(huán)境你可以自行配置,之后我會(huì)在后面的文章中列出來。
你可以在這個(gè)倉庫查看 這第一次 commit 哦!下面皆可以愉快的做自己的博客了!
【單頁面博客從前端到后端】環(huán)境搭建
【單頁面博客從前端到后端】基于 DVA+ANTD 搭建博客前后臺(tái)界面
【單頁面博客從前端到后端】基于 Passport 和 Koa@2 的權(quán)限驗(yàn)證與 DVA 的 Model 設(shè)計(jì)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83357.html
摘要:說到底,當(dāng)自己獨(dú)自開發(fā)從搭建開發(fā)環(huán)境,到前端的每一個(gè)組件,到動(dòng)作交互,再到和后端的數(shù)據(jù)交互,難免遇到不少問題。單頁面博客從前端到后端基于和的權(quán)限驗(yàn)證與的設(shè)計(jì)引入來實(shí)現(xiàn)富文本編輯器是開源的用于構(gòu)建富文本編輯器的框架。 不會(huì)后端的前端,不會(huì)寫單頁面應(yīng)用... 單頁面應(yīng)用的概念已經(jīng)被提出很長時(shí)間了,無論是基于 vue, angular 還是 react,相信大家或是耳濡目染,或是設(shè)身處地都有...
摘要:在的的配置中添加自定義主題由腳手架和官網(wǎng)介紹,我們已經(jīng)自己配置并新建好了主題文件。單頁面博客從前端到后端環(huán)境搭建單頁面博客從前端到后端基于搭建博客前后臺(tái)界面單頁面博客從前端到后端基于和的權(quán)限驗(yàn)證與的設(shè)計(jì) 在上篇文章我們已經(jīng)搭建好了基礎(chǔ)的開發(fā)環(huán)境,接下來會(huì)介紹如何引入 DVA 和 ANTD ,以及在引入過程中需要注意的問題。這里只會(huì)詳細(xì)的書寫部分組件,其他的組件都是大同小異。你可以在 g...
摘要:我們就采用這種方式來進(jìn)行權(quán)限驗(yàn)證。這里我還是使用在中的下新增單頁面博客從前端到后端環(huán)境搭建單頁面博客從前端到后端基于搭建博客前后臺(tái)界面單頁面博客從前端到后端基于和的權(quán)限驗(yàn)證與的設(shè)計(jì) 基于 JWT 的權(quán)限驗(yàn)證 這里有一篇文章描述的已經(jīng)非常詳盡,闡述了 JWT 驗(yàn)證相比較傳統(tǒng)的持久化 session 驗(yàn)證的優(yōu)勢(shì),以及基于 angular 和 express 驗(yàn)證的簡單流程。 基于Json ...
摘要:所以單頁應(yīng)用的部署,需要將所有的頁面請(qǐng)求都返回,瀏覽器下載了后會(huì)自動(dòng)解析并導(dǎo)航到對(duì)應(yīng)頁面??偨Y(jié)單頁應(yīng)用與以前的常規(guī)多頁面應(yīng)用還是有區(qū)別的,開發(fā)過程與后端解耦了,同時(shí)會(huì)出現(xiàn)跨域鑒權(quán)以及應(yīng)用部署的問題。 本文同步發(fā)布于我的個(gè)人博客上 - 單頁應(yīng)用的部署方案 本文主要簡單講一下單頁應(yīng)用的開發(fā)及部署方法,默認(rèn)你懂一些服務(wù)端知識(shí)及nginx知識(shí),如果有任何可以在下方評(píng)論留言。 單頁應(yīng)用 SPA(...
摘要:項(xiàng)目地址這個(gè)項(xiàng)目是為了學(xué)習(xí)而建的,從前端到后端一手包辦。相對(duì)來說,還是有一定難度的,適合有一定編程基礎(chǔ)的人進(jìn)階學(xué)習(xí)。教程一教程二在安裝完后,克隆項(xiàng)目。 項(xiàng)目地址 這個(gè)項(xiàng)目是為了學(xué)習(xí) node 而建的,從前端到后端一手包辦。相對(duì)來說,還是有一定難度的,適合有一定編程基礎(chǔ)的人進(jìn)階學(xué)習(xí)。 如果有問題,歡迎提 issues 注意,本項(xiàng)目的前后端代碼都是放在一起的,前端代碼放在 src 目錄,后...
閱讀 3573·2023-04-25 19:56
閱讀 1681·2021-11-12 10:36
閱讀 1800·2021-11-08 13:19
閱讀 1553·2019-08-30 14:06
閱讀 3045·2019-08-30 11:01
閱讀 1752·2019-08-29 13:23
閱讀 2752·2019-08-29 11:18
閱讀 3439·2019-08-26 13:35