摘要:在這篇文章中我們開始利用我們之前所學搭建一個簡易的開發環境,用以鞏固我們之前學習的知識。
文章首發于我的github及個人博客,github請看https://github.com/huruji/blo...,轉載請注明出處。
在這篇文章中我們開始利用我們之前所學搭建一個簡易的React開發環境,用以鞏固我們之前學習的Webpack知識。首先我們需要明確這次開發環境需要達到的效果:1、能夠編譯JSX語言 2、css樣式使用Sass開發 3.能夠將基礎的ES6轉化為ES5 4.能夠使用ESLint在開發的時候為我們做代碼風格審查
首先,安裝基本使用的webpack、webpack-dev-server
npm i webpack webpack-dev-server -D基本頁面的生成
為了可以生成一個基本的頁面我們使用html-webpack-plugin,為了方便我們定制,我們自己在src定義一個html文件,使用template指定這個文件。
安裝html-webpack-plugin
npm i html-webpack-plugin -D
在src文件夾下生成一個html文件,內容如下:
Title
在webpack.config.js中寫入以下內容作為基本的設置:
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;
此時在命令行中運行以下命令可以看到一切正常運行,盡管目前在瀏覽器上還沒有任何效果:
webpack-dev-server --open編譯es6和jsx語言
在React開發的時候我們使用jsx語言和es6,因此需要使用babel對我們的開發進行一個編譯,使用babel即可:
安裝babel-loader:
npm i babel-loader -D
為了使用這個babel-loader,我們需要安裝babel-core(當我們需要以編程方式使用babel時就需要安裝這個):
npm i babel-core -D
為了編譯es6和jsx需要安裝相應的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文件中寫入以下內容:
{
"presets": [
"es2015",
"react"
]
}
此時我們測試一下是否可以正常編譯jsx和es2015,安裝react和react-dom,同時在src中的main.js和App.js寫入部分內容
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
);
}
在命令行運行命令,可以發現瀏覽器已經正常顯示了,也就是說正常編譯了jsx和es6
webpack-dev-server --open
此時,整個webpack.config.js文件內容如下:
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簡易開發環境",
template: "./src/index.html"
}),
new webpack.HotModuleReplacementPlugin()
]
}
module.exports = config;
編譯Sass樣式
編譯Sass和之前文章提到的一樣,需要使用style-loader、css-loader、sass-loader,首先進行安裝:
npm i style-loader css-loader sass-loader -D
因為sass-loader是依賴node-sass的,同時因為sass-loader的uri是相對于output的,因此需要使用resolve-url-loader
npm i node-sass resolve-url-loader -D
在webpack.config.js中進行配置:
const config = {
// ......
module: {
rules: [
//......
{
test: /.(sass|scss|css)/,
use: [
"style-loader",
"css-loader",
"resolve-url-loader",
"sass-loader?sourceMap"
]
}
]
},
// ......
}
module.exports = config;
在src文件夾中新建一個名為sass的文件夾,同時新建_header.scss、_variablers.scss、main.scss,三個文件內容分別為:
_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";
此時再次運行命令,可以在瀏覽器中看到header部分的樣式已經生效。
此時整個webpack.config.js文件內容如下:
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簡易開發環境",
template: "./src/index.html"
}),
new webpack.HotModuleReplacementPlugin()
]
}
module.exports = config;
配置ESLint為我們做代碼風格檢查
使用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;
新建一個eslint的配置文件.eslintrc.js:
module.exports = {
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true
},
"parser": "babel-eslint"
};
此時運行命令行會發現正常運行,原因是eslint默認所有規則都是禁用的,我們在.eslintrc.js中添加一條簡單的禁用console的規則,當出現console時,將會報warning
module.exports = {
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true
},
"parser": "babel-eslint",
"rules": {
"no-console": 1
}
};
此時再次運行命令,可以發現以下界面,控制臺已經很明確的告訴我們,我們的App.js中出現了console,說明此時eslint已經生效。
但是在一個項目中我們如果配置每一個規則會顯得非常麻煩,因此我們選擇使用airbnb的規則,使用npm安裝:
npm i eslint-config-airbnb -D
安裝完成之后可以發現控制臺告訴我們需要安裝eslint-plugin-jsx-a11y、eslint-plugin-import、eslint-plugin-react,同時安裝時應該大于或者等于某個版本號:
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
}
};
此時,再次運行命令之后可以發現,在命令行和控制臺中都報出了我們的代碼風格問題,如下:
airbnb中的所有規則我們可以根據我們的需要進行重寫,我們注意到其中一條error如下:
JSX not allowed in files with extension ".js" react/jsx-filename-extension
前面的為相應說明,后面的為規則,這條不允許我們在.js文件中書寫JSX語言,后面為對應的規則,顯然是eslint-plugin-react插件的規則,我們可以重寫以允許我們在.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"] }]
}
};
再次運行可以發現這條error已經不存在了。
在項目中解析圖片模塊在之前的文章中我們已經提到過了,我們可以使用file-loader來實現:
npm i file-loader -D
在webpack.config.js中配置:
const config = {
// ......
module: {
rules: [
{
test: /.(png|jpg|svg|gif)/,
use:[
"file-loader"
]
}
]
},
// ......
}
module.exports = config;
此時我們可以引入圖片資源了。
支持更多的ES6方法我們在使用babel的時候我們需要明確知道的一點是,babel默認只是為我們轉化語法層面上的東西(如箭頭函數),并不會為我們去將一些方法進行轉化為es2015的實現,也就是說如果我使用Array.of方法,如果瀏覽器不支持這個方法,及時按照上面的babel轉化也是依舊沒有辦法運行的,我們可以在App.js中使用Array.of方法來測試一下,如下:
Array.of(1,2,3,4).forEach(function(item){
console.log(item);
});
我們這次使用webpack命令直接在dist文件夾中生成相應的文件,我們可以在js文件中找到以下內容:
這就驗證了上文的說法,因此我們需要使用babel-polyfill
首先進行安裝:
npm i install babel-polyfill -D
安裝完成之后我們需要在webpack的入口中進行配置,將webpack的entry修改為以下內容:
entry: ["babel-polyfill","./src/main.js"]開發與生產環境分離
我們現在使用webpack命令為我們打包一下內容,我們會發現打包后的文件非常大,只有部分內容卻打包之后有3000+kb,這是不能用在生產環境上的,如下:
文件體積太大一個重要原因是devtool開啟了inline-source-map方便我們定位bug,同時代碼沒有壓縮也是重要原因之一,因此我們需要將開發和生產環境分離,使用不同的webpack配置。
還記得我們系列之前介紹的webpack-merge嗎?我們通過這個插件可以將公共的配置分離到一起。首先進行安裝
npm i webpack-merge -D
新建一個名為webpack.common.js文件作為公共配置,寫入以下內容:
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簡易開發環境",
template: "./src/index.html"
})
]
}
module.exports = config;
新建一個名為webpack.dev.js文件作為開發環境配置,寫入以下內容:
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;
剛剛我們提到我們在開發環境中應該壓縮混淆代碼同時精簡輸出,因此需要使用uglifyjs-webpack-plugin插件,首先進行安裝:
npm i uglifyjs-webpack-plugin -D
新建一個名為webpack.prod.js的文件作為生產環境配置,寫入以下內容:
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;
因為在開發時我們需要使用的命令是
webpack-dev-server --open --config webpack.dev.js
而在生產中我們需要使用的命令是
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"
}
此時我們只要在命令行中輸入npm run dev即可開啟開發環境,使用npm run build即可自動生成用于生產環境的文件。
使用clean-webpack-plugin現在還有一個問題是我們修改文件之后再次使用npm run build命令則會出現多個js文件,這是因為我們使用了hash占位符,
這個占位符可以保證用戶訪問網站時始終保持最新的js文件,因此我們使用clean-webpack-plugin幫助我們每次刪除dist文件夾的內容
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;
開發src目錄劃分
雖然目前一個簡易的React開發環境已經搭建好了,但是還是需要對src目錄進行劃分以保證良好的開發體驗,以下是劃分的目錄:
└───Components
└───......
└───......
└───Containers
└───......
└───......
└───static
└───sass
└───img
└───index.html
└───main.js
目錄功能相信一眼就能看出來了。這時一個簡易的環境就已經搭建好了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/91780.html
摘要:有沒有辦法實現就局部刷新呢當然是有第十步執行為了實現局部熱加載,我們需要添加插件。 前言 用了3個多月的vue自認為已經是一名合格的vue框架api搬運工,對于vue的api使用到達了一定瓶頸,無奈水平有限,每每深入底層觀賞源碼時候都迷失了自己。 遂決定再找個框架學習學習看看能否突破思維局限,加上本人早已對React、RN技術垂涎已久,于是決定找找教程來學習。無奈第一步就卡在了環境搭...
摘要:插件開發前端掘金作者原文地址譯者插件是為應用添加全局功能的一種強大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內優雅的實現文件分片斷點續傳。 Vue.js 插件開發 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應用添加全局功能的一種強大而且簡單的方式。插....
平日學習接觸過的網站積累,以每月的形式發布。2017年以前看這個網址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進擊的 Promise Effective JavaScript leeheys blog -...
平日學習接觸過的網站積累,以每月的形式發布。2017年以前看這個網址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進擊的 Promise Effective JavaScript leeheys blog -...
閱讀 1665·2021-11-09 09:45
閱讀 1984·2021-11-04 16:09
閱讀 1888·2021-10-14 09:43
閱讀 2028·2021-09-22 15:24
閱讀 1911·2021-09-07 10:06
閱讀 1777·2019-08-30 14:15
閱讀 1208·2019-08-30 12:56
閱讀 1700·2019-08-29 17:22