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