亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

?使用webpack配置多頁面應(yīng)用(MPA)

rainyang / 2595人閱讀

使用webpack配置MPA

為什么需要使用 webpack 構(gòu)建多頁應(yīng)用呢?因?yàn)槟承╉?xiàng)目使用 SPA 不太合適(大多是 SEO 的原因),或者您在做項(xiàng)目時(shí)有其他的需求。
如果你有如下需求:

使用 ES6 進(jìn)行開發(fā)

期望使用面向?qū)ο箝_發(fā)(class)

自動(dòng)壓縮合并 CSS 和 JS 文件

使用 ESLint 進(jìn)行代碼檢查

自動(dòng)生成 HTML 文件

自動(dòng)抽取 CSS 文件 ...

有了這些需求,基本上就必須使用 webpack 了。

安裝依賴

首先是項(xiàng)目中需要使用的依賴安裝。

安裝 webpack 和 webpack-dev-server

npm install webpack webpack-dev-server --save-dev

安裝 webpack-merge

npm install webpack-merge --save-dev

該插件用來對(duì) webpack 配置進(jìn)行合并操作。

安裝 babel 相關(guān)插件

npm install babel-core babel-loader babel-preset-env --save-dev

這系列插件用來對(duì) ES6 語法進(jìn)行轉(zhuǎn)換。

安裝樣式處理相關(guān)插件

npm install css-loader style-loader postcss-loader autoprefixer --save-dev

這系列插件用來處理 CSS 樣式,其中 autoprefixer 是 postcss 的一個(gè)插件,用來自動(dòng)給 CSS 樣式添加前綴。

安裝 file-loader

該插件將在導(dǎo)入圖片、字體等文件時(shí)發(fā)揮作用。PS.您也可以安裝 url-loader 以實(shí)現(xiàn)相同的作用:

npm install file-loader --save-dev
npm install url-loader --save-dev

安裝 ESLint 相關(guān)的插件

npm install eslint eslint-loader --save-dev

這些插件用來對(duì) JavaScript 代碼進(jìn)行檢查。

安裝 html-webpack-plugin 插件

npm install html-webpack-plugin --save-dev

該插件用來自動(dòng)生成 HTML 文件。

安裝 extract-text-webpack-plugin 插件

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

該插件用來將 CSS 抽取到獨(dú)立的文件。

安裝 clean-webpack-plugin 插件

npm install clean-webpack-plugin --save-dev

該插件用來對(duì) dist 文件夾進(jìn)行清理工作,每次打包時(shí)先清理之前的 dist 文件夾。

下面是這些安裝了的所有依賴:
...
  "devDependencies": {
    "autoprefixer": "^7.1.3",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.0",
    "clean-webpack-plugin": "^0.1.16",
    "css-loader": "^0.28.7",
    "eslint": "^4.6.1",
    "eslint-loader": "^1.9.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^0.11.2",
    "html-webpack-plugin": "^2.30.1",
    "postcss-loader": "^2.0.6",
    "style-loader": "^0.18.2",
    "url-loader": "^0.5.9",
    "webpack": "^3.5.5",
    "webpack-dev-server": "^2.7.1",
    "webpack-merge": "^4.1.0"
  },
...
配置文件劃分

使用 webpack 進(jìn)行項(xiàng)目構(gòu)建時(shí),我們有不同的目的,因此最好將配置文件進(jìn)行拆分,以適應(yīng)不同的工作:

├─config
│      config.js
│      webpack.config.base.js
│      webpack.config.dev.js
│      webpack.config.lint.js
│      webpack.config.prod.js
│  webpack.config.js
下面是一些配置的說明:
config.js:一些全局的配置,比如 HTML 文件的路徑、publicPath 等
webpack.config.base.js:最基礎(chǔ)的配置文件
webpack.config.dev.js:開發(fā)環(huán)境配置文件
webpack.config.lint.js:使用 ESLint 代碼檢查時(shí)的配置文件
webpack.config.prod.js:生產(chǎn)環(huán)境配置文件
webpack.config.js:主配置文件,根據(jù)環(huán)境變量引用相應(yīng)的環(huán)境的配置

這些配置文件之間是通過 webpack-merge 這個(gè)插件進(jìn)行合并的。

配置多頁應(yīng)用的關(guān)鍵點(diǎn)

如何使用 webpack 配置多頁面應(yīng)用呢?實(shí)現(xiàn)多頁面應(yīng)用的關(guān)鍵點(diǎn)在哪里呢?首先需要簡單看一下多頁應(yīng)用和單頁應(yīng)用功能的區(qū)別。

單頁應(yīng)用的特點(diǎn):

只有一個(gè)入口頁面(index.html)
這個(gè)單頁頁面(index.html)中需要引入打包后的所有 JavaScript 文件
所有的頁面內(nèi)容完全由 JavaScript 生成
單頁應(yīng)用有自己的路由系統(tǒng),服務(wù)器端沒有和路由對(duì)應(yīng)的文件
···

多頁應(yīng)用的特點(diǎn):

每個(gè)版塊對(duì)應(yīng)一個(gè)頁面
每個(gè)頁面需要對(duì)公共的 JavaScript 進(jìn)行引入
每個(gè)頁面還需要引入和其自身對(duì)應(yīng)的 JavaScript 文件
由于對(duì)應(yīng)了多個(gè)頁面,因此不是所有頁面內(nèi)容都是由 JavaScript 生成的
沒有自己的路由系統(tǒng),服務(wù)器端有對(duì)應(yīng)的靜態(tài)文件
···
拋開生成頁面內(nèi)容和路由系統(tǒng),我們可以看到單頁應(yīng)用和多頁應(yīng)用最大的區(qū)別就是:

單頁應(yīng)用需要在入口頁面引入所有的 JavaScript 文件
多頁應(yīng)用需要在每個(gè)頁面中引入公共的 JavaScript 文件以及其自身的 JavaScript 文件
由于 CSS 文件是可以由 extract-text-webpack-plugin 這個(gè)插件自動(dòng)提取并插入到 HTML 頁面的,因此我們只需要關(guān)心如何在 HTML 頁面中引入 JavaScript 文件了。
webpack 在打包時(shí),會(huì)將入口文件中的 JavaScript 文件打包到某個(gè)目標(biāo)文件中,在不考慮代碼分割提取的情況下,一個(gè)入口文件會(huì)打包為一個(gè)目標(biāo)文件,多個(gè)入口文件會(huì)打包為多個(gè)對(duì)應(yīng)的目標(biāo)文件。
因此,我們可以將每個(gè)多頁頁面中的特有的 JavaScript 文件作為入口文件,在打包時(shí)將對(duì)應(yīng)打包成不同的 bundle 文件(結(jié)果文件),如果你想要的話,還可以在打包時(shí)進(jìn)行代碼分割處理,將公用代碼抽取成一個(gè)文件,然后在 HTML 中引入這些 JavaScript 文件就好了。
總結(jié)一下,使用 webpack 配置多頁應(yīng)用的關(guān)鍵點(diǎn)在于:

將每個(gè)頁面中特有的 JavaScript 文件作為入口文件進(jìn)行打包
在打包后,每個(gè)頁面中都需要引入這些打包后的文件
您可以在打包時(shí)進(jìn)行公用代碼提取,然后在 HTML 文件中引入
說了這么多,其實(shí)就是利用了 webpack 多入口文件進(jìn)行打包。

自動(dòng)生成 HTML 頁面

在使用 webpack 對(duì) JavaScript 文件進(jìn)行打包時(shí),通常需要在打包的文件名中加一個(gè) hash 字符串用來防止緩存,當(dāng)我們修改了 JavaScript 代碼后,打包后的文件名也會(huì)發(fā)生變化。此時(shí)如果手動(dòng)在 HTML 中引用這些 JavaScript 文件,是非常麻煩的。
因此,我們期望能自動(dòng)生成 HTML 文件,并自動(dòng)引用打包后的 JavaScript 文件。所謂自動(dòng)生成 HTML 文件,可以理解為將源代碼的 HTML 復(fù)制到目標(biāo)文件夾中,同時(shí)自動(dòng)引用打包后的 JavaScript 文件。
要完成這項(xiàng)操作,就需要使用前面安裝的 html-webpack-plugin 這個(gè)插件。

html-webpack-plugin 插件的使用

首先,在我的項(xiàng)目中,有這么一些 HTML 頁面,將它們放在 html 文件夾中:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         2017/9/5     18:04           1071 company_intro.html
-a----         2017/9/5     18:04            988 contact_us.html
-a----         2017/9/5     18:04           1131 cooperate.html
-a----         2017/9/5     18:04           1244 enterprise_culture.html
-a----         2017/9/5     18:04           1011 hornors.html
-a----         2017/9/5     18:04           1365 index.html
-a----         2017/9/5     18:04           1769 investment.html
-a----         2017/9/5     18:04           1005 join_us.html
-a----         2017/9/5     18:04           1037 news_center.html
-a----         2017/9/5     18:04            987 news_item.html
-a----         2017/9/5     18:04           1134 operate.html
-a----         2017/9/5     18:04           1255 product.html
-a----         2017/9/5     18:04           1132 schools.html

然后,把這些 HTML 文件名(不要后綴)都寫在 config.js 文件中,以供取用:

module.exports = {
    HTMLDirs:[
        "index",
            "company_intro",
            "enterprise_culture",
            "hornors",
            "news_center",
            "news_item",
            "product",
            "schools",
            "operate",
            "cooperate",
            "join_us",
            "contact_us",
            "investment"
            ],
        }

HTMLDirs 是一個(gè)數(shù)組,其中保存了項(xiàng)目中會(huì)用到的所有 HTML 頁面。
接下來,每個(gè) HTML 頁面都對(duì)應(yīng)一份 JavaScript 代碼,因此在 js 文件夾中建立對(duì)應(yīng)的 JavaScript 文件:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         2017/9/5     18:04           2686 company_intro.js
-a----         2017/9/5     18:04            594 contact_us.js
-a----         2017/9/5     18:04           1725 cooperate.js
-a----         2017/9/8     16:54           3505 enterprise_culture.js
-a----         2017/9/5     18:04           2208 hornors.js
-a----         2017/9/8     16:54           4491 index.js
-a----         2017/9/5     18:04           3180 investment.js
-a----         2017/9/5     18:04           1327 join_us.js
-a----         2017/9/8     16:55           3689 news_center.js
-a----         2017/9/5     18:04           1972 news_item.js
-a----         2017/9/5     18:04           2728 operate.js
-a----         2017/9/5     18:04           2664 product.js
-a----         2017/9/5     18:04           2476 schools.js

這兩項(xiàng)是必須的,只有提供了每個(gè)頁面的 HTML 文件和對(duì)應(yīng)的 JavaScript 文件,才能構(gòu)建多頁面應(yīng)用。
同時(shí),可能每個(gè)頁面都有自己的樣式,因此您也可以在 css 文件夾中建立一些樣式文件:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         2017/9/5     18:04            419 company_intro.css
-a----         2017/9/5     18:04            167 contact_us.css
-a----         2017/9/5     18:04            214 cooperate.css
-a----         2017/9/5     18:04            926 enterprise_culture.css
-a----         2017/9/5     18:04            255 hornors.css
-a----         2017/9/5     18:04            693 investment.css
-a----         2017/9/5     18:04            136 join_us.css
-a----         2017/9/5     18:04            541 news_center.css
-a----         2017/9/5     18:04            623 news_item.css
-a----         2017/9/5     18:04            342 operate.css
-a----         2017/9/5     18:04            236 product.css
-a----         2017/9/5     18:04            213 schools.css

關(guān)于建立樣式這一項(xiàng),不是必須的。
最后,我們就可以使用 html-webpack-plugin 這個(gè)插件來自動(dòng)生成 HTML 文件了,html-webpack-plugin 插件的用法如下:

// 引入插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 引入多頁面文件列表
const { HTMLDirs } = require("./config");
// 通過 html-webpack-plugin 生成的 HTML 集合
let HTMLPlugins = [];
// 入口文件集合
let Entries = {}

// 生成多頁面的集合
HTMLDirs.forEach((page) => {
    const htmlPlugin = new HTMLWebpackPlugin({
        filename: `${page}.html`,
        template: path.resolve(__dirname, `../app/html/${page}.html`),
        chunks: [page, "commons"],
    });
    HTMLPlugins.push(htmlPlugin);
    Entries[page] = path.resolve(__dirname, `../app/js/${page}.js`);
})

在上面的代碼中,首先引入了所需的插件和變量,然后利用 html-webpack-plugin 循環(huán)生成 HTML 頁面。
簡單說下 HTMLWebpackPlugin 構(gòu)造函數(shù)的幾個(gè)參數(shù):

filename:生成的 HTML 文件名,我這里選擇和原始文件名保持一致
template:生成 HTML 文件使用的模板,也就是我們之前在 html 文件夾中建立的那些文件
chunks:生成 HTML 文件時(shí)會(huì)自動(dòng)插入相應(yīng)的代碼片段(也就是 JavaScript 文件),我這里選擇插入每個(gè)頁面對(duì)應(yīng)的 JavaScript 文件,以及最后提取出來的公共文件代碼塊。
關(guān)于 chunks 還需要說明一點(diǎn),chunks 是一個(gè)數(shù)組,在生成 HTML 文件時(shí)會(huì)將數(shù)組中的對(duì)應(yīng)的 JavaScript 片段自動(dòng)插入到 HTML 中,這些片段也就是 webpack 打包時(shí)的 output 選項(xiàng)中的 [name]。這里只需要寫上 [name] 值就行了,無需使用打包生成的完整名稱,因?yàn)檫@會(huì)還沒開始打包呢,打包后生成的名稱咱也不知道。
最后,我們把這些生成 HTML 文件的配置插入到 HTMLPlugins 這個(gè)數(shù)組中,同時(shí)設(shè)置 webpack 的入口文件。

目錄劃分

在這個(gè)腳手架中,我是這樣劃分項(xiàng)目結(jié)構(gòu)的:

    ├─app
    │  ├─css
    │  ├─html
    │  ├─img
    │  ├─js
    │  └─lib
    ├─config
    └─dist
        ├─css
        ├─img
        └─js
    其中 app 是項(xiàng)目的源碼,config 是 webpack 相關(guān)的一些配置文件,dist 是存放打包后的文件,是由 webpack 自動(dòng)生成的。
    更詳細(xì)的文件結(jié)構(gòu)如下:

    │  .babelrc
    │  .eslintrc.js
    │  .gitignore
    │  package.json
    │  postcss.config.js
    │  webpack.config.js
    │  
    ├─app
    │  │  favicon.ico
    │  │  
    │  ├─css
    │  │      main.css
    │  │      
    │  ├─html
    │  │      index.html
    │  │    
    │  │      
    │  ├─img
    │  │      back.png
    │  │      
    │  ├─js
    │  │      ajax.js
    │  │      footer.js
    │  │      index.js
    │  │      nav.js
    │  │      public.js
    │  │      tity_nav.js
    │  │      
    │  └─lib
    │        flexible.js
    │        normalize.css
    │        swiper.css
    │        swiper.js
    │        
    └─config
            config.js
            webpack.config.base.js
            webpack.config.dev.js
            webpack.config.lint.js
            webpack.config.prod.js
package.json

所有的功能都是從 package.json 的 scripts 入口開始執(zhí)行的,我想要腳手架有以下功能:

開發(fā)環(huán)境構(gòu)建

生產(chǎn)環(huán)境構(gòu)建

ESLint 代碼檢查環(huán)境

生產(chǎn)環(huán)境構(gòu)建后的服務(wù)器預(yù)覽環(huán)境

在開發(fā)或代碼檢查環(huán)境,需要啟用 webpack-dev-server 命令,生產(chǎn)環(huán)境構(gòu)建需要啟用 webpack 命令,預(yù)覽環(huán)境需要啟用 http-server 環(huán)境。

上文介紹時(shí)把 http-server 給落下了,您現(xiàn)在可以進(jìn)行如下安裝:

npm install http-server --save-dev

scripts 命令行配置如下:

  "scripts": {
    "dev": "set NODE_ENV=dev && webpack-dev-server --open",
    "build": "set NODE_ENV=prod && webpack -p",
    "lint": "set NODE_ENV=lint && webpack-dev-server --open",
    "serve": "http-server ./dist -p 8888 -o",
    "serve2": "http-server ./dist -p 8888"
  },

下面是整個(gè) package.json 文件:

{
    "name": "xxx",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "dev": "set NODE_ENV=dev && webpack-dev-server --open",
    "build": "set NODE_ENV=prod && webpack -p",
    "lint": "set NODE_ENV=lint && webpack-dev-server --open",
    "serve": "http-server ./dist -p 8888 -o",
    "serve2": "http-server ./dist -p 8888"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "autoprefixer": "^7.1.3",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-transform-es2015-spread": "^6.22.0",
    "babel-preset-env": "^1.6.0",
    "clean-webpack-plugin": "^0.1.16",
    "css-loader": "^0.28.7",
    "eslint": "^4.5.0",
    "eslint-loader": "^1.9.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^0.11.2",
    "html-webpack-plugin": "^2.30.1",
    "http-server": "^0.10.0",
    "postcss-loader": "^2.0.6",
    "style-loader": "^0.18.2",
    "url-loader": "^0.5.9",
    "webpack": "^3.5.5",
    "webpack-dev-server": "^2.7.1",
    "webpack-merge": "^4.1.0"
    },
    "dependencies": {}
}
啟用環(huán)境

如果您想啟用某個(gè)環(huán)境,需要使用 npm run xxx 命令:

npm run dev:進(jìn)入開發(fā)環(huán)境

npm run build:進(jìn)入生產(chǎn)環(huán)境

npm run lint:執(zhí)行代碼檢查

npm run serve:服務(wù)器環(huán)境下預(yù)覽(打開瀏覽器)

npm run serve2:服務(wù)器環(huán)境下預(yù)覽(不打開瀏覽器)

默認(rèn)情況下,使用這些命令都會(huì)先引入和 package.js 同目錄下的 webpack.config.js 文件。由于我們不會(huì)將所有的配置都放在 webpack.config.js 中,而是過環(huán)境變量進(jìn)行區(qū)分,在 webpack.config.js 中引用其他的配置文件。
設(shè)置環(huán)境變量采用的語法:

set NODE_ENV=xxx
這里我們?yōu)殚_發(fā)、生產(chǎn)、代碼檢查和預(yù)覽這幾個(gè)環(huán)境設(shè)置了環(huán)境變量。

webpack.config.js

webpack.config.js 文件比較簡單,只有兩行代碼,其作用就是用來引用其他的配置文件:

// 獲取環(huán)境命令,并去除首尾空格
const env = process.env.NODE_ENV.replace(/(s*$)|(^s*)/ig,"");
// 根據(jù)環(huán)境變量引用相關(guān)的配置文件
module.exports = require(`./config/webpack.config.${env}.js`)
webpack.config.base.js

webpack.config.base.js 是最基礎(chǔ)的配置文件,包含了這些環(huán)境都可能使用到的配置。

1)相關(guān)插件引入
const path = require("path");
// 引入插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 清理 dist 文件夾
const CleanWebpackPlugin = require("clean-webpack-plugin")
// 抽取 css
const ExtractTextPlugin = require("extract-text-webpack-plugin");
#### 2)自動(dòng)生成 HTML 的配置

// 引入多頁面文件列表
const config = require("./config");
// 通過 html-webpack-plugin 生成的 HTML 集合
let HTMLPlugins = [];
// 入口文件集合
let Entries = {}

// 生成多頁面的集合
config.HTMLDirs.forEach((page) => {
    const htmlPlugin = new HTMLWebpackPlugin({
        filename: `${page}.html`,
        template: path.resolve(__dirname, `../app/html/${page}.html`),
        chunks: [page, "commons"],
    });
    HTMLPlugins.push(htmlPlugin);
    Entries[page] = path.resolve(__dirname, `../app/js/${page}.js`);
})
3)主配置文件一覽
module.exports = {
    // 入口文件
    entry:Entries,
    // 啟用 sourceMap
    devtool:"cheap-module-source-map",
    // 輸出文件
    output:{},
    // 加載器
    module:{
        rules:[
        ],
    },
    // 插件
    plugins:[],
}
4)配置 css 加載器
{
    // 對(duì) css 后綴名進(jìn)行處理
    test:/.css$/,
    // 不處理 node_modules 文件中的 css 文件
    exclude: /node_modules/,
    // 抽取 css 文件到多帶帶的文件夾
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        // 設(shè)置 css 的 publicPath
        publicPath: config.cssPublicPath,
        use: [{
                loader:"css-loader",
                options:{
                    // 開啟 css 壓縮
                    minimize:true,
                }
            },
            {
                loader:"postcss-loader",
            }
        ]
    })
},

這里有兩點(diǎn)需要說明:
A.publicPath:在 css 中設(shè)置背景圖像的 url 時(shí),經(jīng)常會(huì)找不到圖片(默認(rèn)會(huì)在 css 文件所在的文件夾中尋找),這里設(shè)置 extract-text-webpack-plugin 插件的 publicPath 為圖片文件夾所在的目錄,就可以順利找到圖片了。
在 config.js 中,設(shè)置 cssPublicPath 的值:

cssPublicPath:"../"
B.postcss 我主要用來自動(dòng)添加 css 前綴以及一點(diǎn)美化操作,在使用 postcss 時(shí),需要在 postcss.config.js 中進(jìn)行配置:

module.exports = {  
    plugins: {  
    "autoprefixer": {
        browsers: ["last 5 version","Android >= 4.0"],
        //是否美化屬性值 默認(rèn):true 
        cascade: true,
        //是否去掉不必要的前綴 默認(rèn):true 
        remove: true
    }  
    }  
}  
5)配置 js 加載器

js 加載器的配置如下:

{
    test: /.js$/,
    exclude: /node_modules/,
    use: {
        loader: "babel-loader",
        options: {
            presets: ["env"]
        }
    }
},
6)配置圖片加載器

圖片加載器的配置如下:

{
    test: /.(png|svg|jpg|gif)$/,
    use:{
        loader:"file-loader",
        options:{
            // 打包生成圖片的名字
            name:"[name].[ext]",
            // 圖片的生成路徑
            outputPath:config.imgOutputPath
        }
    }
},

outputPath 規(guī)定了輸出圖片的位置,默認(rèn)情況下,圖片在打包時(shí)會(huì)和所有的 HTML/CSS/JS 文件打包到一起,通過設(shè)置 outputPath 值可以將所有的圖片都打包到一個(gè)多帶帶的文件中。
設(shè)置 config.js 的 imgOutputPath:

imgOutputPath:"img/",
在打包時(shí),會(huì)將所有的圖片打包到 dist 文件夾下的 img 文件夾中。

7)配置自定義字體加載器

自定義字體加載器的配置如下:

{
    test: /.(woff|woff2|eot|ttf|otf)$/,
    use:["file-loader"]
}
8)插件配置

插件配置如下:

plugins:[
    // 自動(dòng)清理 dist 文件夾
    new CleanWebpackPlugin(["dist"]),
    // 將 css 抽取到某個(gè)文件夾
    new ExtractTextPlugin(config.cssOutputPath),        
    // 自動(dòng)生成 HTML 插件
    ...HTMLPlugins
],

同打包圖片,在抽取 css 時(shí)也可以指定抽取的目錄,只需將路徑傳入 extract-text-webpack-plugin 插件的構(gòu)造函數(shù)中。
配置 config.js 的 cssOutputPath 選項(xiàng):

cssOutputPath:"./css/styles.css",

這里將所有的 css 提取到 dist 文件夾下的 css 文件夾中,并命名為 style.css。

webpack.config.base.js 詳細(xì)配置

下面是 webpack.config.base.js 的詳細(xì)配置文件:

const path = require("path");
// 引入插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 清理 dist 文件夾
const CleanWebpackPlugin = require("clean-webpack-plugin")
// 抽取 css
const ExtractTextPlugin = require("extract-text-webpack-plugin");
// 引入多頁面文件列表
const config = require("./config");
// 通過 html-webpack-plugin 生成的 HTML 集合
let HTMLPlugins = [];
// 入口文件集合
let Entries = {}

// 生成多頁面的集合
config.HTMLDirs.forEach((page) => {
    const htmlPlugin = new HTMLWebpackPlugin({
        filename: `${page}.html`,
        template: path.resolve(__dirname, `../app/html/${page}.html`),
        chunks: [page, "commons"],
    });
    HTMLPlugins.push(htmlPlugin);
    Entries[page] = path.resolve(__dirname, `../app/js/${page}.js`);
})

module.exports = {
    entry:Entries,
    devtool:"cheap-module-source-map",
    output:{
        filename:"js/[name].bundle.[hash].js",
        path:path.resolve(__dirname,"../dist")
    },
    // 加載器
    module:{
        rules:[
            {
                // 對(duì) css 后綴名進(jìn)行處理
                test:/.css$/,
                // 不處理 node_modules 文件中的 css 文件
                exclude: /node_modules/,
                // 抽取 css 文件到多帶帶的文件夾
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    // 設(shè)置 css 的 publicPath
                    publicPath: config.cssPublicPath,
                    use: [{
                            loader:"css-loader",
                            options:{
                                // 開啟 css 壓縮
                                minimize:true,
                            }
                        },
                        {
                            loader:"postcss-loader",
                        }
                    ]
                })
            },
            {
                test: /.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["env"]
                    }
                }
            },
            {
                test: /.(png|svg|jpg|gif)$/,
                use:{
                    loader:"file-loader",
                    options:{
                        // 打包生成圖片的名字
                        name:"[name].[ext]",
                        // 圖片的生成路徑
                        outputPath:config.imgOutputPath
                    }
                }
            },
            {
                test: /.(woff|woff2|eot|ttf|otf)$/,
                use:["file-loader"]
            }
        ],
    },
    plugins:[
        // 自動(dòng)清理 dist 文件夾
        new CleanWebpackPlugin(["dist"]),
        // 將 css 抽取到某個(gè)文件夾
        new ExtractTextPlugin(config.cssOutputPath),        
        // 自動(dòng)生成 HTML 插件
        ...HTMLPlugins
    ],
}
webpack.config.dev.js

這個(gè)配置文件主要用來在開發(fā)環(huán)境使用,需要 webpack-dev-server 這個(gè)插件提供支持。該文件的配置如下:

// 引入基礎(chǔ)配置文件
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入配置文件
const config = require("./config");
// 合并配置文件
module.exports = webpackMerge(webpackBase,{
    // 配置 webpack-dev-server
    devServer:{
        // 項(xiàng)目根目錄
        contentBase:config.devServerOutputPath,
        // 錯(cuò)誤、警告展示設(shè)置
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

其中,webpack-merge 這個(gè)插件用來對(duì)配置文件進(jìn)行合并,在 webpack.config.base.js 的基礎(chǔ)上合并新的配置。
devServer 配置項(xiàng)的 contentBase 項(xiàng)是項(xiàng)目的根目錄,也就是我們的 dist 目錄,區(qū)別在于這個(gè) dist 目錄不是硬盤上的 dist 目錄,而是存在于內(nèi)存中的 dist 目錄。在使用 webpack-dev-server 時(shí),將會(huì)以這個(gè)內(nèi)存中的 dist 目錄作為根目錄。
devServer 的 overlay 選項(xiàng)中設(shè)置了展示錯(cuò)誤和警告,這樣當(dāng)代碼發(fā)生錯(cuò)誤時(shí),會(huì)將錯(cuò)誤信息投射到瀏覽器上,方便我們開發(fā)。
這里將 contentBase 指向了 config 中的一個(gè)配置:

devServerOutputPath:"../dist",
webpack.config.prod.js

該配置文件用來在生產(chǎn)環(huán)境啟用,主要用來壓縮、合并和抽取 JavaScript 代碼,并將項(xiàng)目文件打包至硬盤上的 dist 文件夾中。

// 引入基礎(chǔ)配置
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入 webpack
const webpack = require("webpack");
// 合并配置文件
module.exports = webpackMerge(webpackBase,{
    plugins:[
        // 代碼壓縮
        new webpack.optimize.UglifyJsPlugin({
            // 開啟 sourceMap
            sourceMap: true
        }),
        // 提取公共 JavaScript 代碼
        new webpack.optimize.CommonsChunkPlugin({
            // chunk 名為 commons
            name: "commons",
            filename: "[name].bundle.js",
        }),
    ]
});

在抽取公共的 JavaScript 代碼時(shí),我們將公共代碼抽取為 commons.bundle.js,這個(gè)公共代碼的 chunk(name)名就是 commons,在使用 html-webpack-plugin 自動(dòng)生成 HTML 文件時(shí)會(huì)引用這個(gè) chunk。

webpack.config.lint.js

這項(xiàng)配置用來進(jìn)行代碼檢查,配置如下:

const webpackBase = require("./webpack.config.base");
const webpackMerge = require("webpack-merge");
const config = require("./config");
module.exports = webpackMerge(webpackBase,{
    module:{
        rules:[
            {
                test: /.js$/,
                // 強(qiáng)制先進(jìn)行 ESLint 檢查
                enforce: "pre",
                // 不對(duì) node_modules 和 lib 文件夾中的代碼進(jìn)行檢查
                exclude: /node_modules|lib/,
                loader: "eslint-loader",
                options: {
                    // 啟用自動(dòng)修復(fù)
                    fix:true,
                    // 啟用警告信息
                    emitWarning:true,
                }
            },
        ]
    },
    devServer:{
        contentBase:config.devServerOutputPath,
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

在使用 eslint-loader 時(shí),我們?cè)O(shè)置了 enforce:"pre" 選項(xiàng),這個(gè)選項(xiàng)表示在處理 JavaScript 之前先啟用 ESLint 代碼檢查,然后再使用 babel 等 loader 對(duì) JavaScript 進(jìn)行編譯。
在 eslint-loader 的 options 選項(xiàng)中,設(shè)置了自動(dòng)修復(fù)和啟用警告信息,這樣當(dāng)我們的代碼出現(xiàn)問題時(shí),ESLint 會(huì)首先嘗試自動(dòng)修復(fù)(如將雙引號(hào)改為單引號(hào)),對(duì)于無法自動(dòng)修復(fù)的問題,將以警告或錯(cuò)誤的信息進(jìn)行展示。

配置 .eslintrc.js

要想使用 ESLint 進(jìn)行代碼檢查,除了使用 eslint-loader 之外,還需針對(duì) ESLint 本身進(jìn)行配置,這就需要一個(gè) .eslintrc.js 文件。該文件的配置如下:

module.exports = {
    env: {
    browser: true,
    commonjs: true,
    es6: true,
    node: true,
    },
    extends: "eslint:recommended",
    parserOptions: {
    sourceType: "module",
    },
    rules: {
    "comma-dangle": ["error", "always-multiline"],
    indent: ["error", 2],
    "linebreak-style": ["error", "unix"],
    quotes: ["error", "single"],
    semi: ["error", "always"],
    "no-unused-vars": ["warn"],
    "no-console": 0,
    },
};
package.json
{
    "name": "xxx",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "dev": "set NODE_ENV=dev && webpack-dev-server --open",
    "build": "set NODE_ENV=prod && webpack -p",
    "lint": "set NODE_ENV=lint && webpack-dev-server --open",
    "serve": "http-server ./dist -p 8888 -o",
    "serve2": "http-server ./dist -p 8888"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "autoprefixer": "^7.1.3",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-transform-es2015-spread": "^6.22.0",
    "babel-preset-env": "^1.6.0",
    "clean-webpack-plugin": "^0.1.16",
    "css-loader": "^0.28.7",
    "eslint": "^4.5.0",
    "eslint-loader": "^1.9.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^0.11.2",
    "html-webpack-plugin": "^2.30.1",
    "http-server": "^0.10.0",
    "postcss-loader": "^2.0.6",
    "style-loader": "^0.18.2",
    "url-loader": "^0.5.9",
    "webpack": "^3.5.5",
    "webpack-dev-server": "^2.7.1",
    "webpack-merge": "^4.1.0"
    },
    "dependencies": {}
}
.gitignore
node_modules
dist
npm-debug.log

.babelrc

{
    "plugins": ["transform-es2015-spread"]
}
.eslintrc.js
module.exports = {
    env: {
    browser: true,
    commonjs: true,
    es6: true,
    node: true,
    },
    extends: "eslint:recommended",
    parserOptions: {
    sourceType: "module",
    },
    rules: {
    "comma-dangle": ["error", "always-multiline"],
    indent: ["error", 2],
    "linebreak-style": ["error", "unix"],
    quotes: ["error", "single"],
    semi: ["error", "always"],
    "no-unused-vars": ["warn"],
    "no-console": 0,
    },
};
postcss.config.js
module.exports = {  
    plugins: {  
    "autoprefixer": {
        browsers: ["last 5 version","Android >= 4.0"],
        //是否美化屬性值 默認(rèn):true 
        cascade: true,
        //是否去掉不必要的前綴 默認(rèn):true 
        remove: true
    }  
    }  
} 
config.js
module.exports = {
    HTMLDirs:[
        "index",
        "company_intro",
        "enterprise_culture",
        "hornors",
        "news_center",
        "news_item",
        "product",
        "schools",
        "operate",
        "cooperate",
        "join_us",
        "contact_us",
        "investment"
    ],
    cssPublicPath:"../",
    imgOutputPath:"img/",
    cssOutputPath:"./css/styles.css",
    devServerOutputPath:"../dist",

}
webpack.config.js
// 獲取環(huán)境命令,并去除首尾空格
const env = process.env.NODE_ENV.replace(/(s*$)|(^s*)/ig,"");
// 根據(jù)環(huán)境變量引用相關(guān)的配置文件
module.exports = require(`./config/webpack.config.${env}.js`)
webpack.config.base.js

const path = require("path");
// 引入插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 清理 dist 文件夾
const CleanWebpackPlugin = require("clean-webpack-plugin")
// 抽取 css
const ExtractTextPlugin = require("extract-text-webpack-plugin");
// 引入多頁面文件列表
const config = require("./config");
// 通過 html-webpack-plugin 生成的 HTML 集合
let HTMLPlugins = [];
// 入口文件集合
let Entries = {}

// 生成多頁面的集合
config.HTMLDirs.forEach((page) => {
    const htmlPlugin = new HTMLWebpackPlugin({
        filename: `${page}.html`,
        template: path.resolve(__dirname, `../app/html/${page}.html`),
        chunks: [page, "commons"],
    });
    HTMLPlugins.push(htmlPlugin);
    Entries[page] = path.resolve(__dirname, `../app/js/${page}.js`);
})

module.exports = {
    entry:Entries,
    devtool:"cheap-module-source-map",
    output:{
        filename:"js/[name].bundle.[hash].js",
        path:path.resolve(__dirname,"../dist")
    },
    // 加載器
    module:{
        rules:[
            {
                // 對(duì) css 后綴名進(jìn)行處理
                test:/.css$/,
                // 不處理 node_modules 文件中的 css 文件
                exclude: /node_modules/,
                // 抽取 css 文件到多帶帶的文件夾
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    // 設(shè)置 css 的 publicPath
                    publicPath: config.cssPublicPath,
                    use: [{
                            loader:"css-loader",
                            options:{
                                // 開啟 css 壓縮
                                minimize:true,
                            }
                        },
                        {
                            loader:"postcss-loader",
                        }
                    ]
                })
            },
            {
                test: /.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["env"]
                    }
                }
            },
            {
                test: /.(png|svg|jpg|gif)$/,
                use:{
                    loader:"file-loader",
                    options:{
                        // 打包生成圖片的名字
                        name:"[name].[ext]",
                        // 圖片的生成路徑
                        outputPath:config.imgOutputPath
                    }
                }
            },
            {
                test: /.(woff|woff2|eot|ttf|otf)$/,
                use:["file-loader"]
            }
        ],
    },
    plugins:[
        // 自動(dòng)清理 dist 文件夾
        new CleanWebpackPlugin(["dist"]),
        // 將 css 抽取到某個(gè)文件夾
        new ExtractTextPlugin(config.cssOutputPath),        
        // 自動(dòng)生成 HTML 插件
        ...HTMLPlugins
    ],
}
webpack.config.dev.js
// 引入基礎(chǔ)配置文件
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入配置文件
const config = require("./config");
// 合并配置文件
module.exports = webpackMerge(webpackBase,{
    // 配置 webpack-dev-server
    devServer:{
        // 項(xiàng)目根目錄
        contentBase:config.devServerOutputPath,
        // 錯(cuò)誤、警告展示設(shè)置
        overlay:{
            errors:true,
            warnings:true
        }
    }
});
webpack.config.prod.js
// 引入基礎(chǔ)配置
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入 webpack
const webpack = require("webpack");
// 合并配置文件
module.exports = webpackMerge(webpackBase,{
    plugins:[
        // 代碼壓縮
        new webpack.optimize.UglifyJsPlugin({
            // 開啟 sourceMap
            sourceMap: true
        }),
        // 提取公共 JavaScript 代碼
        new webpack.optimize.CommonsChunkPlugin({
            // chunk 名為 commons
            name: "commons",
            filename: "[name].bundle.js",
        }),
    ]
});
webpack.config.lint.js
const webpackBase = require("./webpack.config.base");
const webpackMerge = require("webpack-merge");
const config = require("./config");
module.exports = webpackMerge(webpackBase,{
    module:{
        rules:[
            {
                test: /.js$/,
                // 強(qiáng)制先進(jìn)行 ESLint 檢查
                enforce: "pre",
                // 不對(duì) node_modules 和 lib 文件夾中的代碼進(jìn)行檢查
                exclude: /node_modules|lib/,
                loader: "eslint-loader",
                options: {
                    // 啟用自動(dòng)修復(fù)
                    fix:true,
                    // 啟用警告信息
                    emitWarning:true,
                }
            },
        ]
    },
    devServer:{
        contentBase:config.devServerOutputPath,
        overlay:{
            errors:true,
            warnings:true
        }
    }
});
項(xiàng)目結(jié)構(gòu)
│  .babelrc
│  .eslintrc.js
│  .gitignore
│  package.json
│  postcss.config.js
│  webpack.config.js
│  
├─app
│  │  favicon.ico
│  │  
│  ├─css
│  │      main.css
│  │      
│  ├─html
│  │      index.html
│  │    
│  │      
│  ├─img
│  │      back.png
│  │      
│  ├─js
│  │      ajax.js
│  │      footer.js
│  │      index.js
│  │      nav.js
│  │      public.js
│  │      tity_nav.js
│  │      
│  └─lib
│        flexible.js
│        normalize.css
│        swiper.css
│        swiper.js
│        
└─config
        config.js
        webpack.config.base.js
        webpack.config.dev.js
        webpack.config.lint.js
        webpack.config.prod.js

注釋: 想引用jquery而不是每個(gè)頁面都引用只需要: 引入jquery后如果開啟lint檢查模式 可以正常使用的前提是每個(gè)頁面都require 一次

webpack.config.base.js

cnpm i jquery --save

const ProvidePlugin = new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
});
引入sass

webpack.config.base.js

{
    // s?css => scss或者css
    test:/.s?css$/,
    // 不處理 node_modules 文件中的 css 文件
    exclude: /node_modules/,
    // 抽取 css 文件到多帶帶的文件夾
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        // 設(shè)置 css 的 publicPath
        publicPath: config.cssPublicPath,//在 css 中設(shè)置背景圖像的 url 時(shí),經(jīng)常會(huì)找不到圖片(默認(rèn)會(huì)在 css 文件所在的文件夾中尋找),這里設(shè)置 extract-text-webpack-plugin 插件的 publicPath 為圖片文件夾所在的目錄,就可以順利找到圖片了
        use: [{
                loader:"css-loader",
                options:{
                    // 開啟 css 壓縮
                    minimize:true,
                }
            },
            {
                loader:"postcss-loader",
            },
            {
                loader:"sass-loader", 
                //啟用sass 雖然在這只寫了sass-loader 但還要下載node-sass
            }
        ]
    })
},
如果import了類似swiper這種庫函數(shù) 但不處理modules里面的swiper,所以這里要允許除了node_modules里面的swiper的其他所有文件

webpack.config.base.js

{
    test: /.js$/,
    exclude: /^node_modules*swiper$/, 
    use: {
        loader: "babel-loader",
        options: {
            presets: ["env"]
        }
    }
},

? github地址:點(diǎn)我

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/100539.html

相關(guān)文章

  • Javascript 打包工具

    摘要:所以,打包工具就出現(xiàn)了,它可以幫助做這些繁瑣的工作。打包工具介紹僅介紹款主流的打包工具,,,,以發(fā)布時(shí)間為順序。它定位是模塊打包器,而屬于構(gòu)建工具。而且在其他的打包工具在處理非網(wǎng)頁文件比如等基本還是需要借助它來實(shí)現(xiàn)。 本文當(dāng)時(shí)寫在本地,發(fā)現(xiàn)換電腦很不是方便,在這里記錄下。 前端的打包工具 打包工具可以更好的管理html,css,javascript,使用可以錦上添花,不使用也沒關(guān)系...

    Sleepy 評(píng)論0 收藏0
  • 使用 Webpack1.x 搭建 (MultiPage Application,MPA) 基礎(chǔ)框架

    摘要:初始化項(xiàng)目官方文檔項(xiàng)目地址項(xiàng)目搭建簡單記錄一下命令,網(wǎng)上有很多文章不多做介紹。希望可以提供一個(gè)基礎(chǔ)的架構(gòu)。 初始化項(xiàng)目 webpack官方文檔:https://www.webpackjs.com/con...github項(xiàng)目地址:https://github.com/Zhanghongw... 項(xiàng)目搭建簡單記錄一下命令,網(wǎng)上有很多文章不多做介紹。希望可以提供一個(gè)基礎(chǔ)的架構(gòu)。 持續(xù)更新....

    yy736044583 評(píng)論0 收藏0
  • 淺談使用 Vue 構(gòu)建前端 10w+ 代碼量的單頁面應(yīng)用開發(fā)底層

    摘要:其實(shí)就是我們開始掛載上去的我們?cè)谶@里出去,我們就可以在回調(diào)里面只處理我們的業(yè)務(wù)邏輯,而其他如斷網(wǎng)超時(shí)服務(wù)器出錯(cuò)等均通過攔截器進(jìn)行統(tǒng)一處理。 showImg(https://segmentfault.com/img/remote/1460000015472616?w=845&h=622); 開始之前 隨著業(yè)務(wù)的不斷累積,目前我們 ToC 端主要項(xiàng)目,除去 node_modules, bu...

    rickchen 評(píng)論0 收藏0
  • 淺談使用 Vue 構(gòu)建前端 10w+ 代碼量的單頁面應(yīng)用開發(fā)底層

    摘要:其實(shí)就是我們開始掛載上去的我們?cè)谶@里出去,我們就可以在回調(diào)里面只處理我們的業(yè)務(wù)邏輯,而其他如斷網(wǎng)超時(shí)服務(wù)器出錯(cuò)等均通過攔截器進(jìn)行統(tǒng)一處理。 showImg(https://segmentfault.com/img/remote/1460000015472616?w=845&h=622); 開始之前 隨著業(yè)務(wù)的不斷累積,目前我們 ToC 端主要項(xiàng)目,除去 node_modules, bu...

    Backache 評(píng)論0 收藏0
  • 項(xiàng)目:(MPA應(yīng)用)企業(yè)展示 目錄

    項(xiàng)目框架 基礎(chǔ)框架:https://segmentfault.com/a/11...使用之前 webpack 搭建的框架。 項(xiàng)目源碼 github 地址:https://github.com/Zhanghongw... 頁面開發(fā) 地址:https://segmentfault.com/a/11...

    wenhai.he 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<