1.事先我们要创建一个文件夹,叫stage
2.在文件夹里创建一个read.me文件在文件里写上对文件的描述
一个react的脚手架
# main functionalities
- npm scripts [dev product deploy]
- babel[ES6 ES5]
- webpack [图片、CSS、js等处理]
- jest[单元测试]
# file structure
|- src
|- |- app
|- |- components
|- |- global
|- |- |- reset.css
3.好了 , 然后接下来我们git init一下将其用git来管理,顺便按照上面的描述创建文件夹如图
4.然后接下来我们先要下载babel转译工具,先touch .babelrc创建一个.babelrc文件,接着npm init创建一个package.json,将scripts里面的内容改一下,改成
"scripts": {
"dev": "echo \"hello dev\"",
"prod": "echo \"hello prod\""
}
然后在git bash里输入npm run dev 看看会出现什么,如果出现hello dev
说明没问题。
5.然后我们要来下载babel依赖了,我们一个个来装,首先我们要装es6转译的,还有jsx语法转译的。第一步先在之前创建的.babelrc文件里输入
{
"presets": [
"stage-0",
"es2015",
"react"
]
}
然后在git bash里输入
$ npm install babel-preset-stage-0 babel-preset-es2015 babel-preset-react --verbose --save-dev
下载完依赖以后,我们就可以尝试转译es67语法了,在scripts里面增加
"babel": "babel src/app -d dist"
然后npm运行npm run babel
将app里面的js文件转化为es5语法,当然必须先在app里创建一个.js文件并输入依稀es67语法才能转译成功。
6.我们还需要用webpack来处理我们的js.css.图片等资源,所以我们创建一个webpack文件夹,为什么需要一个文件夹而不是一个webpack文件呢,因为我们需要适配多种环境,生产环境,线上环境等,所以需要多个webpack文件。接着在webpack文件夹里创建三个文件,分别是
base.config.js
dev.config.js
prod.config.js
然后安装webpack,
$ npm i webpack --save-dev
7.进到base.config.js里面,开始写一个基本的配置文件
const path = require('path') //path是node.js自带的路径工具
module.exports = {
entry: {
sale: "./sale.js"
},
output: {
path: path.resolve(process.cwd(), "dist"), //path.resolve(process.cwd(),) 指当前node启动目录
filename: "[name].js" //输出文件name
},
module: {
rules: [
{
test: /\.jsx?$/, //相应的文件
loader: 'babel-loader' //处理的插件
},
{
test: /\.css$/,
loader: 'css-loader'
},
{
test: /\.scss$/,
loader: 'sass-loader'
},
{
test: /\.less/,
loader: 'less-loader'
},
{
test: /\.(.png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/,
loader: "file-loader"
}
]
},
}
然后安装相应的依赖
$ npm i babel-loader css-loader less-loader sass-loader file-loader --save-dev --verbose
安装好之后呢,我们先测试一下代码到底能不能work,将package.json里的scripts里的dev改成
"dev": "webpack --config webpack/base.config.js"
然后
npm run dev
跑完之后你会发现它会报错,报错内容是cant resolve sale.js,找不到sale.js文件,因为webpack entry入口的启动上下文就是node.js的启动上下文,所以要加上相应路径,将entry改为
entry: {
sale: "./src/app/sale.js"
}
然后重新npm run dev
你会发现dist里多了一个sale.js的文件,转译成功。
不过如果每个文件都加个前缀会很麻烦,所以我们手动配置一下webpack的编译上下文,在 base.config.js里加上
context: path.resolve(process.cwd(), "src/app")
然后把我们的entry改成
entry: {
sale: "./sale.js"
}
也可以跑成功了。
不过我们的入口文件可能会比较多,所以我们把入口文件也分离出来单独放在一个文件里,在webpack文件夹里重新创建一个entry.js。
entry.js
module.exports = {
sale: "./sale.js"
}
base.config.js
const entry = require('./entry');
module.exports = {
entry: entry,
}
我们可以在app文件夹里再创建一个list.js,里面我们可以随便写
list.js
const b = "aaaa"
console.log(b)
然后改一下entry.js
entry.js
module.exports = {
sale: "./sale.js",
list: "./list.js"
}
这样我们不用动base.config.js就可以增加文件了
8.不过前端不仅有js还有css等。那么这个css文件怎么进入我们的项目呢。我们先在app文件夹下新建一个sale.css文件,随便输入点内容
sale.css
.a {
color: yellow;
}
同时手动引入一下css文件
sale.js
import "./sale.css"
let a = 1;
console.log(a)
然后我们跑一下npm run dev 发现能成功跑起来,css文件就成功引入了,
不过我们发现每次改代码都要重新跑一遍dev,这个太麻烦,我们再用webpack的watch功能
在base.config.js文件里加上
watch: true,
然后重新跑一遍,然后我们会发现,我们改代码他就会自己重新刷新而不用重新跑npm了。(不过配置文件更改还是要重新跑的)
然后我们查看一下dist里面的文件,发现里面只有list.js和sale.js两个文件,然后看sale.js里面的代码,
发现.a {color: yellow}竟然在js文件里面,可是我们要的是css文件独立出来啊,那么我们需要怎么做呢。
9.我们再base.config.js里面只告诉了用什么插件处理css,没有告诉它把文件拿出来。这个时候我们要安装一个插件
$ npm install --save-dev extract-text-webpack-plugin
安装完之后呢,我们可以看看这个插件是怎么用的,可以看下面这个网站
https://github.com/webpack-contrib/extract-text-webpack-plugin
看上面的usage,然后经过更改,我们的base.config.js变成了这样
const path = require('path');
const entry = require('./entry');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
context: path.resolve(process.cwd(), "src/app"),
entry: entry,
watch: true,
output: {
path: path.resolve(process.cwd(), "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
},
{
test: /\.less/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'less-loader']
})
},
{
test: /\.(.png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/,
loader: "file-loader?name=[name]_[sha512:hash:base64:7].[ext]"
}
]
},
plugins: [
new ExtractTextPlugin("style.css"),
]
}
写好配置后我们再安装一下,style.loader
$ npm install style-loader --save-dev
然后跑一下项目,然后一个基本配置项目成功了。我们可以写个less或sass文件简单测试一下。
10.接下来,我们要处理我们的图片文件。首先在src文件夹下创建一个img文件夹,存放图片。可以从网上随便下一张图片放进去。有了图片我们就可以测试一下我们的项目能不能处理图片。打开刚刚简单写的less文件
sale.less
.a {
color: yellow;
.b {
color: red;
}
.c {
background: url('../img/2cun.jpg');
}
}
然后你会发现dist里面会有一张和你之前放进img文件夹里一样的图片。
11.不过随着文件的增加,我们不能把所有的css、图片都放在同一个文件夹里,我们必须把他们单独分开。把css和图片单独放在文件夹里。改一下file-loader和plugins的配置
base.config.js
test: /\.(.png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/,
loader: "file-loader",
options: {
name: 'assets/[name]_[sha512:hash:base64:7].[ext]'
}
plugins: [
new ExtractTextPlugin("css/[name].css"),
]
12.我们发现配置里面并没有html,接下来我们要引入html文件,在那之前,我们先下载一个工具——webpack-dev-server
首先我们先下载下来
$ npm i webpack-dev-server --save-dev
然后改一下package.json的dev命令
"scripts": {
"dev": "webpack-dev-server --config webpack/base.config.js",
"prod": "echo \"hello prod\"",
"babel": "babel src/app -d dist"
},
然后我们跑npm run dev就会产生一个8080端口。这个时候我们再建一个html文件就完事了。不过如果想改变它的输出端口号,我们可以对base.config.js文件进行编辑
devServer: {
contentBase: path.resolve(process.cwd(), "指定的文件地址"),
compress: true,
port: 9000
}
为了建立html,我们要再引入一个插件webpack-html-plugin
$ npm install html-webpack-plugin --save-dev
引入后参照文档
https://github.com/jantimon/html-webpack-plugin
将文档里的内容拷贝进来
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};
就是在我们的base.config.js里面加入这一行代码
const HtmlWebpackPlugin = require('html-webpack-plugin');
然后改一下plugins
plugins: [
new ExtractTextPlugin("css/[name].css"),
new HtmlWebpackPlugin()
]
然后再跑dev,发现我们打开了一个空的html,里面引入了sale.js和sale.css。不过我们在真的项目里面并不能这么做。
13.我们在src文件里新建一个base文件夹,创建一个webpack.template.html
模板代码,编辑它
webpack.template.html
<html>
<head>
<title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
然后配置这么改
plugins: [
new ExtractTextPlugin("css/[name].css"),
new HtmlWebpackPlugin({
title: 'sale',
template: path.resolve(
process.cwd(),
'src/base/webpack.template.html'),
filename: 'sale.html',
chunks: ['sale'] //sale.html引入的css和js文件资源
})
]
测试一下,npm run dev就会打开端口相应的资源。
14.测试完成接下来我们继续,在stage文件夹里新建一个sample文件夹,里面新建sale.html。同时编辑一下
sale.html
<html>
<head>
<title>sale</title>
<link href="/dist/sale.css" ref="stylesheet">
</head>
<body>
<div id="root"></div>
<script src="/dist/sale.js">
</body>
</html>
然后改一下base.config.js里的derServer和output
output: {
publicPath: "/dist", //加了一个publicPath,webpack-dev-server会去读取相应路径下面的文件,所以上面可以得到sale.js等文件
path: path.resolve(process.cwd(), "dist"),
filename: "[name].js"
},
devServer: {
contentBase: path.resolve(process.cwd(), "sample"),
compress: true,
port: 9000
}
然后npm run dev就能得到一个html页面了
15.接下来我们就要开始引入框架了,这里我们先引入的是react,直接下载
$ npm install react --save
$ npm install react-dom --save
同时在base.config.js里加个resolve
resolve: {
extensions: [".js", ".jsx", ".json"]
},
编辑sale.js
import './sale.less'
import React from 'react';
import ReactDom from 'react-dom'
const node = document.getElementById('root')
ReactDom.render("hello world", node);
let a = "2";
console.log(a)
这样一个小型的脚手架就完成了
16.但是想想这个脚手架还缺了点什么,缺什么呢,还缺单元测试!!
我们通过下载jest工具来帮我们完成单元测试。
$ npm install --save-dev jest
然后在package.json里增加一条:
scripts: {
"text": "jest"
}
接着在src下面创建一个 service文件夹,在里面创建一个 calculate.js,再创建一个calculate.text.js做测试
calculate.js
function calculate(a, b) {
return a + b;
}
module.exports = calculate;
calculate.text.js
const calculate = require('./calculate');
test('adds 1 + 2 to equal 3', () => {
expect(calculate(1, 2)).toBe(3);
});
然后npm run test开始测试,如果是pass,则运行成功 代码没问题
17.接下来我们要配置生产环境下的webpack配置,用webpack-gulify打包压缩
npm i -D uglifyjs-webpack-plugin
然后编辑prod.webpack.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const baseWebpackPlugin = require('./base.config.js');
const plugins = baseWebpackPlugin.plugins;
const newPlugins = plugins.concat([new UglifyJsPlugin()]);
module.exports = Object.assign({},
baseWebpackPlugin,
{
plugins: newPlugins
}
)
package.json
"scripts": {
"prod": "webpack --config webpack/prod.config.js --optimize-minimize",
},
既然生产环境分离出来了,那dev环境也分离一下将base.config.js里的
watch: true,
devServer: {
contentBase: path.resolve(process.cwd(),"sample"),
compress: true,
port: 9000
}
转移到dev.config.js里
const baseWebpackConfig = require('./base.config.js');
const devWebpackPartialConfig = {
watch: true,
devServer: {
contentBase: path.resolve(process.cwd(),"sample"),
compress: true,
port: 9000
}
}
module.exports = Object.assign({},
baseWebpackConfig,
devWebpackPartialConfig
)
18.好了 到现在,一个基本的脚手架就完成了,如果需要要vue,就直接下载就行了。