如何從零開始建前端一個腳手架

1.事先我們要創(chuàng)建一個文件夾,叫stage
2.在文件夾里創(chuàng)建一個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來管理,順便按照上面的描述創(chuàng)建文件夾如圖


QQ截圖20171121224751.jpg

4.然后接下來我們先要下載babel轉(zhuǎn)譯工具,先touch .babelrc創(chuàng)建一個.babelrc文件,接著npm init創(chuàng)建一個package.json,將scripts里面的內(nèi)容改一下,改成

"scripts": {
    "dev": "echo \"hello dev\"",
    "prod": "echo \"hello prod\""
  }

然后在git bash里輸入npm run dev 看看會出現(xiàn)什么,如果出現(xiàn)hello dev說明沒問題。

5.然后我們要來下載babel依賴了,我們一個個來裝,首先我們要裝es6轉(zhuǎn)譯的,還有jsx語法轉(zhuǎn)譯的。第一步先在之前創(chuàng)建的.babelrc文件里輸入

{
  "presets": [
    "stage-0",
    "es2015",
    "react"
  ]
}

然后在git bash里輸入

$ npm install babel-preset-stage-0 babel-preset-es2015 babel-preset-react --verbose --save-dev

下載完依賴以后,我們就可以嘗試轉(zhuǎn)譯es67語法了,在scripts里面增加
"babel": "babel src/app -d dist"
然后npm運行npm run babel將app里面的js文件轉(zhuǎn)化為es5語法,當(dāng)然必須先在app里創(chuàng)建一個.js文件并輸入依稀es67語法才能轉(zhuǎn)譯成功。

6.我們還需要用webpack來處理我們的js.css.圖片等資源,所以我們創(chuàng)建一個webpack文件夾,為什么需要一個文件夾而不是一個webpack文件呢,因為我們需要適配多種環(huán)境,生產(chǎn)環(huán)境,線上環(huán)境等,所以需要多個webpack文件。接著在webpack文件夾里創(chuàng)建三個文件,分別是

base.config.js 
dev.config.js
prod.config.js

然后安裝webpack,
$ npm i webpack --save-dev

7.進(jìn)到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(),) 指當(dāng)前node啟動目錄
          filename: "[name].js"     //輸出文件name
    },
module: {
        rules: [
            {
                test: /\.jsx?$/,        //相應(yīng)的文件
                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"
            }
        ]
    },
}

然后安裝相應(yīng)的依賴

$ 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
跑完之后你會發(fā)現(xiàn)它會報錯,報錯內(nèi)容是cant resolve sale.js,找不到sale.js文件,因為webpack entry入口的啟動上下文就是node.js的啟動上下文,所以要加上相應(yīng)路徑,將entry改為

entry: {
        sale: "./src/app/sale.js"
}

然后重新npm run dev你會發(fā)現(xiàn)dist里多了一個sale.js的文件,轉(zhuǎn)譯成功。
不過如果每個文件都加個前綴會很麻煩,所以我們手動配置一下webpack的編譯上下文,在 base.config.js里加上
context: path.resolve(process.cwd(), "src/app")
然后把我們的entry改成

entry: {
        sale: "./sale.js"
}

也可以跑成功了。
不過我們的入口文件可能會比較多,所以我們把入口文件也分離出來單獨放在一個文件里,在webpack文件夾里重新創(chuàng)建一個entry.js。

entry.js

module.exports = {
    sale: "./sale.js"
}

base.config.js

const entry = require('./entry');

module.exports = { 
    entry: entry,
}

我們可以在app文件夾里再創(chuàng)建一個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文件怎么進(jìn)入我們的項目呢。我們先在app文件夾下新建一個sale.css文件,隨便輸入點內(nèi)容

sale.css

.a {
    color: yellow;
}

同時手動引入一下css文件
sale.js

import "./sale.css"
let a = 1;
console.log(a)

然后我們跑一下npm run dev 發(fā)現(xiàn)能成功跑起來,css文件就成功引入了,
不過我們發(fā)現(xiàn)每次改代碼都要重新跑一遍dev,這個太麻煩,我們再用webpack的watch功能

在base.config.js文件里加上

watch: true,

然后重新跑一遍,然后我們會發(fā)現(xiàn),我們改代碼他就會自己重新刷新而不用重新跑npm了。(不過配置文件更改還是要重新跑的)

然后我們查看一下dist里面的文件,發(fā)現(xiàn)里面只有l(wèi)ist.js和sale.js兩個文件,然后看sale.js里面的代碼,


NUYJKTEWM6EM_7}JD({$)`M.png

發(fā)現(xiàn).a {color: yellow}竟然在js文件里面,可是我們要的是css文件獨立出來啊,那么我們需要怎么做呢。

9.我們再base.config.js里面只告訴了用什么插件處理css,沒有告訴它把文件拿出來。這個時候我們要安裝一個插件

$ npm install --save-dev extract-text-webpack-plugin

安裝完之后呢,我們可以看看這個插件是怎么用的,可以看下面這個網(wǎng)站
https://github.com/webpack-contrib/extract-text-webpack-plugin

看上面的usage,然后經(jīng)過更改,我們的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文件夾下創(chuàng)建一個img文件夾,存放圖片??梢詮木W(wǎng)上隨便下一張圖片放進(jìn)去。有了圖片我們就可以測試一下我們的項目能不能處理圖片。打開剛剛簡單寫的less文件

sale.less

.a {
    color: yellow;
    .b {
        color: red;
    }
    .c {
        background: url('../img/2cun.jpg');
    }
}

然后你會發(fā)現(xiàn)dist里面會有一張和你之前放進(jìn)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.我們發(fā)現(xiàn)配置里面并沒有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就會產(chǎn)生一個8080端口。這個時候我們再建一個html文件就完事了。不過如果想改變它的輸出端口號,我們可以對base.config.js文件進(jìn)行編輯

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
將文檔里的內(nèi)容拷貝進(jìn)來

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,發(fā)現(xiàn)我們打開了一個空的html,里面引入了sale.js和sale.css。不過我們在真的項目里面并不能這么做。

13.我們在src文件里新建一個base文件夾,創(chuàng)建一個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就會打開端口相應(yīng)的資源。

14.測試完成接下來我們繼續(xù),在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會去讀取相應(yīng)路徑下面的文件,所以上面可以得到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.但是想想這個腳手架還缺了點什么,缺什么呢,還缺單元測試?。?br> 我們通過下載jest工具來幫我們完成單元測試。

$ npm install --save-dev jest

然后在package.json里增加一條:

scripts: {
        "text": "jest"
}

接著在src下面創(chuàng)建一個 service文件夾,在里面創(chuàng)建一個 calculate.js,再創(chuàng)建一個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.接下來我們要配置生產(chǎn)環(huán)境下的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", 
  },

既然生產(chǎn)環(huán)境分離出來了,那dev環(huán)境也分離一下將base.config.js里的

watch: true,
devServer: {
        contentBase: path.resolve(process.cwd(),"sample"),
        compress: true,
        port: 9000
    }

轉(zhuǎn)移到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.好了 到現(xiàn)在,一個基本的腳手架就完成了,如果需要要vue,就直接下載就行了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容