摘要:在這篇文章中我們開始利用我們之前所學(xué)搭建一個(gè)簡易的開發(fā)環(huán)境,用以鞏固我們之前學(xué)習(xí)的知識(shí)。
文章首發(fā)于我的github及個(gè)人博客,github請看https://github.com/huruji/blo...,轉(zhuǎn)載請注明出處。
在這篇文章中我們開始利用我們之前所學(xué)搭建一個(gè)簡易的React開發(fā)環(huán)境,用以鞏固我們之前學(xué)習(xí)的Webpack知識(shí)。首先我們需要明確這次開發(fā)環(huán)境需要達(dá)到的效果:1、能夠編譯JSX語言 2、css樣式使用Sass開發(fā) 3.能夠?qū)⒒A(chǔ)的ES6轉(zhuǎn)化為ES5 4.能夠使用ESLint在開發(fā)的時(shí)候?yàn)槲覀冏龃a風(fēng)格審查
首先,安裝基本使用的webpack、webpack-dev-server
npm i webpack webpack-dev-server -D基本頁面的生成
為了可以生成一個(gè)基本的頁面我們使用html-webpack-plugin,為了方便我們定制,我們自己在src定義一個(gè)html文件,使用template指定這個(gè)文件。
安裝html-webpack-plugin
npm i html-webpack-plugin -D
在src文件夾下生成一個(gè)html文件,內(nèi)容如下:
Title
在webpack.config.js中寫入以下內(nèi)容作為基本的設(shè)置:
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const config = { entry: "./src/main.js", output: { filename: "bundle-[hash].js", path: path.join(__dirname, "dist") }, devtool:"inline-source-map", devServer: { contentBase: "./dist", hot: true }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html" }), new webpack.HotModuleReplacementPlugin() ] } module.exports = config;
此時(shí)在命令行中運(yùn)行以下命令可以看到一切正常運(yùn)行,盡管目前在瀏覽器上還沒有任何效果:
webpack-dev-server --open編譯es6和jsx語言
在React開發(fā)的時(shí)候我們使用jsx語言和es6,因此需要使用babel對我們的開發(fā)進(jìn)行一個(gè)編譯,使用babel即可:
安裝babel-loader:
npm i babel-loader -D
為了使用這個(gè)babel-loader,我們需要安裝babel-core(當(dāng)我們需要以編程方式使用babel時(shí)就需要安裝這個(gè)):
npm i babel-core -D
為了編譯es6和jsx需要安裝相應(yīng)的preset,即需要安裝babel-preset-react和babel-preset-es2015:
npm i babel-preset-es2015 babel-preset-react -D
在webpack的配置文件中引入babel-loader:
const config = { //.... module:{ rules: [ { test: /.(js|jsx)$/, use:[ "babel-loader" ] } ] } // ...... } module.exports = config;
配置babel的配置文件,在.babelrc文件中寫入以下內(nèi)容:
{ "presets": [ "es2015", "react" ] }
此時(shí)我們測試一下是否可以正常編譯jsx和es2015,安裝react和react-dom,同時(shí)在src中的main.js和App.js寫入部分內(nèi)容
npm i react react-dom -S
main.js
import ReactDOM from "react-dom"; import React from "react"; import App from "./App"; ReactDOM.render(, document.getElementById("app"));
App.js
import React from "react"; export default function () { return (React); }
在命令行運(yùn)行命令,可以發(fā)現(xiàn)瀏覽器已經(jīng)正常顯示了,也就是說正常編譯了jsx和es6
webpack-dev-server --open
此時(shí),整個(gè)webpack.config.js文件內(nèi)容如下:
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const config = { entry: "./src/main.js", output: { filename: "bundle-[hash].js", path: path.join(__dirname, "dist") }, devtool:"inline-source-map", devServer: { contentBase: "./dist", hot: true }, module: { rules: [ { test: /.(js|jsx)/, use:[ "babel-loader" ] } ] }, plugins: [ new HtmlWebpackPlugin({ title:"React簡易開發(fā)環(huán)境", template: "./src/index.html" }), new webpack.HotModuleReplacementPlugin() ] } module.exports = config;編譯Sass樣式
編譯Sass和之前文章提到的一樣,需要使用style-loader、css-loader、sass-loader,首先進(jìn)行安裝:
npm i style-loader css-loader sass-loader -D
因?yàn)閟ass-loader是依賴node-sass的,同時(shí)因?yàn)閟ass-loader的uri是相對于output的,因此需要使用resolve-url-loader
npm i node-sass resolve-url-loader -D
在webpack.config.js中進(jìn)行配置:
const config = { // ...... module: { rules: [ //...... { test: /.(sass|scss|css)/, use: [ "style-loader", "css-loader", "resolve-url-loader", "sass-loader?sourceMap" ] } ] }, // ...... } module.exports = config;
在src文件夾中新建一個(gè)名為sass的文件夾,同時(shí)新建_header.scss、_variablers.scss、main.scss,三個(gè)文件內(nèi)容分別為:
_variablers.scss
$bgColor: red; $fontColor: #fff;
_header.scss
.header{ background: $bgColor; color: $fontColor; height:300px; }
main.scss
@import "variables" ,"header"
在main.js中引入main.scss文件:
import "./sass/main.scss";
此時(shí)再次運(yùn)行命令,可以在瀏覽器中看到header部分的樣式已經(jīng)生效。
此時(shí)整個(gè)webpack.config.js文件內(nèi)容如下:
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const config = { entry: "./src/main.js", output: { filename: "bundle-[hash].js", path: path.join(__dirname, "dist") }, devtool:"inline-source-map", devServer: { contentBase: "./dist", hot: true }, module: { rules: [ { test: /.(js|jsx)/, use:[ "babel-loader" ] },{ test: /.(sass|scss|css)/, use: [ "style-loader", "css-loader", "resolve-url-loader", "sass-loader?sourceMap" ] } ] }, plugins: [ new HtmlWebpackPlugin({ title:"React簡易開發(fā)環(huán)境", template: "./src/index.html" }), new webpack.HotModuleReplacementPlugin() ] } module.exports = config;配置ESLint為我們做代碼風(fēng)格檢查
使用eslint首先安裝eslint和eslint-loader:
npm i eslint eslint-loader -D
為了讓eslint支持es6我們需要將eslint的解析器修改為babel-eslint,使用npm安裝
npm i babel-eslint -D
在webpack.config.js中配置eslint-loader
const config = { // ...... module: { rules: [ { test: /.(js|jsx)/, use:[ "babel-loader", "eslint-loader" ] } ] }, // ...... } module.exports = config;
新建一個(gè)eslint的配置文件.eslintrc.js:
module.exports = { "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "env": { "browser": true, "node": true }, "parser": "babel-eslint" };
此時(shí)運(yùn)行命令行會(huì)發(fā)現(xiàn)正常運(yùn)行,原因是eslint默認(rèn)所有規(guī)則都是禁用的,我們在.eslintrc.js中添加一條簡單的禁用console的規(guī)則,當(dāng)出現(xiàn)console時(shí),將會(huì)報(bào)warning
module.exports = { "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "env": { "browser": true, "node": true }, "parser": "babel-eslint", "rules": { "no-console": 1 } };
此時(shí)再次運(yùn)行命令,可以發(fā)現(xiàn)以下界面,控制臺(tái)已經(jīng)很明確的告訴我們,我們的App.js中出現(xiàn)了console,說明此時(shí)eslint已經(jīng)生效。
但是在一個(gè)項(xiàng)目中我們?nèi)绻渲妹恳粋€(gè)規(guī)則會(huì)顯得非常麻煩,因此我們選擇使用airbnb的規(guī)則,使用npm安裝:
npm i eslint-config-airbnb -D
安裝完成之后可以發(fā)現(xiàn)控制臺(tái)告訴我們需要安裝eslint-plugin-jsx-a11y、eslint-plugin-import、eslint-plugin-react,同時(shí)安裝時(shí)應(yīng)該大于或者等于某個(gè)版本號(hào):
npm i eslint-plugin-jsx-a11y@5.1.1 eslint-plugin-import@2.7.0 eslint-plugin-react@7.1.0 -D
在.eslintrc.js文件中使用extends指定繼承自airbnb的配置,如下:
module.exports = { "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "extends": "airbnb", "env": { "browser": true, "node": true }, "parser": "babel-eslint", "rules": { "no-console": 1 } };
此時(shí),再次運(yùn)行命令之后可以發(fā)現(xiàn),在命令行和控制臺(tái)中都報(bào)出了我們的代碼風(fēng)格問題,如下:
airbnb中的所有規(guī)則我們可以根據(jù)我們的需要進(jìn)行重寫,我們注意到其中一條error如下:
JSX not allowed in files with extension ".js" react/jsx-filename-extension
前面的為相應(yīng)說明,后面的為規(guī)則,這條不允許我們在.js文件中書寫JSX語言,后面為對應(yīng)的規(guī)則,顯然是eslint-plugin-react插件的規(guī)則,我們可以重寫以允許我們在.js文件中書寫JSX,如下:
module.exports = { "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "extends": "airbnb", "env": { "browser": true, "node": true }, "parser": "babel-eslint", "rules": { "no-console": 1, "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] } };
再次運(yùn)行可以發(fā)現(xiàn)這條error已經(jīng)不存在了。
在項(xiàng)目中解析圖片模塊在之前的文章中我們已經(jīng)提到過了,我們可以使用file-loader來實(shí)現(xiàn):
npm i file-loader -D
在webpack.config.js中配置:
const config = { // ...... module: { rules: [ { test: /.(png|jpg|svg|gif)/, use:[ "file-loader" ] } ] }, // ...... } module.exports = config;
此時(shí)我們可以引入圖片資源了。
支持更多的ES6方法我們在使用babel的時(shí)候我們需要明確知道的一點(diǎn)是,babel默認(rèn)只是為我們轉(zhuǎn)化語法層面上的東西(如箭頭函數(shù)),并不會(huì)為我們?nèi)⒁恍┓椒ㄟM(jìn)行轉(zhuǎn)化為es2015的實(shí)現(xiàn),也就是說如果我使用Array.of方法,如果瀏覽器不支持這個(gè)方法,及時(shí)按照上面的babel轉(zhuǎn)化也是依舊沒有辦法運(yùn)行的,我們可以在App.js中使用Array.of方法來測試一下,如下:
Array.of(1,2,3,4).forEach(function(item){ console.log(item); });
我們這次使用webpack命令直接在dist文件夾中生成相應(yīng)的文件,我們可以在js文件中找到以下內(nèi)容:
這就驗(yàn)證了上文的說法,因此我們需要使用babel-polyfill
首先進(jìn)行安裝:
npm i install babel-polyfill -D
安裝完成之后我們需要在webpack的入口中進(jìn)行配置,將webpack的entry修改為以下內(nèi)容:
entry: ["babel-polyfill","./src/main.js"]開發(fā)與生產(chǎn)環(huán)境分離
我們現(xiàn)在使用webpack命令為我們打包一下內(nèi)容,我們會(huì)發(fā)現(xiàn)打包后的文件非常大,只有部分內(nèi)容卻打包之后有3000+kb,這是不能用在生產(chǎn)環(huán)境上的,如下:
文件體積太大一個(gè)重要原因是devtool開啟了inline-source-map方便我們定位bug,同時(shí)代碼沒有壓縮也是重要原因之一,因此我們需要將開發(fā)和生產(chǎn)環(huán)境分離,使用不同的webpack配置。
還記得我們系列之前介紹的webpack-merge嗎?我們通過這個(gè)插件可以將公共的配置分離到一起。首先進(jìn)行安裝
npm i webpack-merge -D
新建一個(gè)名為webpack.common.js文件作為公共配置,寫入以下內(nèi)容:
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const config = { entry: ["babel-polyfill","./src/main.js"], output: { filename: "bundle-[hash].js", path: path.join(__dirname, "dist") }, plugins: [ new HtmlWebpackPlugin({ title:"React簡易開發(fā)環(huán)境", template: "./src/index.html" }) ] } module.exports = config;
新建一個(gè)名為webpack.dev.js文件作為開發(fā)環(huán)境配置,寫入以下內(nèi)容:
const merge = require("webpack-merge"); const common = require("./webpack.common"); const webpack = require("webpack"); const config = merge(common, { devtool:"inline-source-map", devServer: { contentBase: "./dist", hot: true }, module: { rules: [ { test: /.(js|jsx)/, use:[ "babel-loader", "eslint-loader" ] },{ test: /.(sass|scss|css)/, use: [ "style-loader", "css-loader", "resolve-url-loader", "sass-loader?sourceMap" ] },{ test: /.(png|jpg|svg|gif)/, use:[ "file-loader" ] } ] }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }); module.exports = config;
剛剛我們提到我們在開發(fā)環(huán)境中應(yīng)該壓縮混淆代碼同時(shí)精簡輸出,因此需要使用uglifyjs-webpack-plugin插件,首先進(jìn)行安裝:
npm i uglifyjs-webpack-plugin -D
新建一個(gè)名為webpack.prod.js的文件作為生產(chǎn)環(huán)境配置,寫入以下內(nèi)容:
const merge = require("webpack-merge"); const common = require("./webpack.common"); const UglifyJSPlugin = require("uglifyjs-webpack-plugin"); const config = merge(common, { devtool:false, module: { rules: [ { test: /.(js|jsx)/, use:[ "babel-loader" ] },{ test: /.(sass|scss|css)/, use: [ "style-loader", "css-loader", "resolve-url-loader", "sass-loader?sourceMap" ] },{ test: /.(png|jpg|svg|gif)/, use:[ "file-loader" ] } ] }, plugins:[ new UglifyJSPlugin() ] }); module.exports = config;
因?yàn)樵陂_發(fā)時(shí)我們需要使用的命令是
webpack-dev-server --open --config webpack.dev.js
而在生產(chǎn)中我們需要使用的命令是
webpack --config webpack.prod.js
為了精簡我們在命令行中的輸入我們將這些命令寫在package.json中
"scripts": { "dev": "webpack-dev-server --open --colors --progress --inline --config webpack.dev.js", "build": "webpack --colors --progress --config webpack.prod.js" }
此時(shí)我們只要在命令行中輸入npm run dev即可開啟開發(fā)環(huán)境,使用npm run build即可自動(dòng)生成用于生產(chǎn)環(huán)境的文件。
使用clean-webpack-plugin現(xiàn)在還有一個(gè)問題是我們修改文件之后再次使用npm run build命令則會(huì)出現(xiàn)多個(gè)js文件,這是因?yàn)槲覀兪褂昧薶ash占位符,
這個(gè)占位符可以保證用戶訪問網(wǎng)站時(shí)始終保持最新的js文件,因此我們使用clean-webpack-plugin幫助我們每次刪除dist文件夾的內(nèi)容
npm i clean-webpack-plugin -D
在webpack.prod.js中引用:
const merge = require("webpack-merge"); const common = require("./webpack.common"); const UglifyJSPlugin = require("uglifyjs-webpack-plugin"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const config = merge(common, { // ...... plugins:[ new CleanWebpackPlugin(["./dist"]), new UglifyJSPlugin() ] }); module.exports = config;開發(fā)src目錄劃分
雖然目前一個(gè)簡易的React開發(fā)環(huán)境已經(jīng)搭建好了,但是還是需要對src目錄進(jìn)行劃分以保證良好的開發(fā)體驗(yàn),以下是劃分的目錄:
└───Components └───...... └───...... └───Containers └───...... └───...... └───static └───sass └───img └───index.html └───main.js
目錄功能相信一眼就能看出來了。這時(shí)一個(gè)簡易的環(huán)境就已經(jīng)搭建好了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91780.html
摘要:有沒有辦法實(shí)現(xiàn)就局部刷新呢當(dāng)然是有第十步執(zhí)行為了實(shí)現(xiàn)局部熱加載,我們需要添加插件。 前言 用了3個(gè)多月的vue自認(rèn)為已經(jīng)是一名合格的vue框架api搬運(yùn)工,對于vue的api使用到達(dá)了一定瓶頸,無奈水平有限,每每深入底層觀賞源碼時(shí)候都迷失了自己。 遂決定再找個(gè)框架學(xué)習(xí)學(xué)習(xí)看看能否突破思維局限,加上本人早已對React、RN技術(shù)垂涎已久,于是決定找找教程來學(xué)習(xí)。無奈第一步就卡在了環(huán)境搭...
摘要:插件開發(fā)前端掘金作者原文地址譯者插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實(shí)現(xiàn)文件分片斷點(diǎn)續(xù)傳。 Vue.js 插件開發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡單的方式。插....
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
閱讀 1422·2021-11-09 09:45
閱讀 1790·2021-11-04 16:09
閱讀 1454·2021-10-14 09:43
閱讀 1818·2021-09-22 15:24
閱讀 1598·2021-09-07 10:06
閱讀 1601·2019-08-30 14:15
閱讀 984·2019-08-30 12:56
閱讀 1566·2019-08-29 17:22