➹运用webpack设置多页面运用(MPA)

运用webpack设置MPA

为何须要运用 webpack 构建多页运用呢?因为某些项目运用 SPA 不太适宜(大多是 SEO 的缘由),或许您在做项目时有其他的需求。
假如你有以下需求:

  • 运用 ES6 举行开辟
  • 希冀运用面向对象开辟(class)
  • 自动紧缩兼并 CSS 和 JS 文件
  • 运用 ESLint 举行代码搜检
  • 自动天生 HTML 文件
  • 自动抽取 CSS 文件 …

有了这些需求,基本上就必需运用 webpack 了。

装置依靠

起首是项目中须要运用的依靠装置。

  1. 装置 webpack 和 webpack-dev-server
npm install webpack webpack-dev-server --save-dev
  1. 装置 webpack-merge
npm install webpack-merge --save-dev

该插件用来对 webpack 设置举行兼并操纵。

  1. 装置 babel 相干插件
npm install babel-core babel-loader babel-preset-env --save-dev

这系列插件用来对 ES6 语法举行转换。

  1. 装置款式处置惩罚相干插件
npm install css-loader style-loader postcss-loader autoprefixer --save-dev

这系列插件用来处置惩罚 CSS 款式,个中 autoprefixer 是 postcss 的一个插件,用来自动给 CSS 款式增加前缀。

  1. 装置 file-loader

该插件将在导入图片、字体等文件时发挥作用。PS.您也能够装置 url-loader 以完成雷同的作用:

npm install file-loader --save-dev
npm install url-loader --save-dev
  1. 装置 ESLint 相干的插件
npm install eslint eslint-loader --save-dev

这些插件用来对 JavaScript 代码举行搜检。

  1. 装置 html-webpack-plugin 插件
npm install html-webpack-plugin --save-dev

该插件用来自动天生 HTML 文件。

  1. 装置 extract-text-webpack-plugin 插件
npm install extract-text-webpack-plugin --save-dev

该插件用来将 CSS 抽取到自力的文件。

  1. 装置 clean-webpack-plugin 插件
npm install clean-webpack-plugin --save-dev

该插件用来对 dist 文件夹举行清算事情,每次打包时先清算之前的 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 举行项目构建时,我们有差别的目的,因而最好将设置文件举行拆分,以顺应差别的事情:

├─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:最基本的设置文件
webpack.config.dev.js:开辟环境设置文件
webpack.config.lint.js:运用 ESLint 代码搜检时的设置文件
webpack.config.prod.js:临盆环境设置文件
webpack.config.js:主设置文件,依据环境变量援用响应的环境的设置

这些设置文件之间是经由过程 webpack-merge 这个插件举行兼并的。

设置多页运用的症结点

怎样运用 webpack 设置多页面运用呢?完成多页面运用的症结点在那里呢?起首须要简朴看一下多页运用和单页运用功用的辨别。

单页运用的特性:

只要一个进口页面(index.html)
这个单页页面(index.html)中须要引入打包后的一切 JavaScript 文件
一切的页面内容完全由 JavaScript 天生
单页运用有自身的路由体系,服务器端没有和路由对应的文件
···

多页运用的特性:

每一个版块对应一个页面
每一个页面须要对大众的 JavaScript 举行引入
每一个页面还须要引入和其自身对应的 JavaScript 文件
因为对应了多个页面,因而不是一切页面内容都是由 JavaScript 天生的
没有自身的路由体系,服务器端有对应的静态文件
···
抛开天生页面内容和路由体系,我们能够看到单页运用和多页运用最大的辨别就是:

单页运用须要在进口页面引入一切的 JavaScript 文件
多页运用须要在每一个页面中引入大众的 JavaScript 文件以及其自身的 JavaScript 文件
因为 CSS 文件是能够由 extract-text-webpack-plugin 这个插件自动提取并插进去到 HTML 页面的,因而我们只须要体贴怎样在 HTML 页面中引入 JavaScript 文件了。
webpack 在打包时,会将进口文件中的 JavaScript 文件打包到某个目的文件中,在不斟酌代码支解提取的情况下,一个进口文件会打包为一个目的文件,多个进口文件会打包为多个对应的目的文件。
因而,我们能够将每一个多页页面中的特有的 JavaScript 文件作为进口文件,在打包时将对应打包成差别的 bundle 文件(效果文件),假如你想要的话,还能够在打包时举行代码支解处置惩罚,将公用代码抽取成一个文件,然后在 HTML 中引入这些 JavaScript 文件就好了。
总结一下,运用 webpack 设置多页运用的症结点在于:

将每一个页面中特有的 JavaScript 文件作为进口文件举行打包
在打包后,每一个页面中都须要引入这些打包后的文件
您能够在打包时举行公用代码提取,然后在 HTML 文件中引入
说了这么多,实在就是应用了 webpack 多进口文件举行打包。

自动天生 HTML 页面

在运用 webpack 对 JavaScript 文件举行打包时,一般须要在打包的文件名中加一个 hash 字符串用来防备缓存,当我们修改了 JavaScript 代码后,打包后的文件名也会发作变化。此时假如手动在 HTML 中援用这些 JavaScript 文件,是异常贫苦的。
因而,我们希冀能自动天生 HTML 文件,并自动援用打包后的 JavaScript 文件。所谓自动天生 HTML 文件,能够理解为将源代码的 HTML 复制到目的文件夹中,同时自动援用打包后的 JavaScript 文件。
要完成这项操纵,就须要运用前面装置的 html-webpack-plugin 这个插件。

html-webpack-plugin 插件的运用

起首,在我的项目中,有这么一些 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 是一个数组,个中保留了项目中会用到的一切 HTML 页面。
接下来,每一个 HTML 页面都对应一份 JavaScript 代码,因而在 js 文件夹中竖立对应的 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

这两项是必需的,只要供应了每一个页面的 HTML 文件和对应的 JavaScript 文件,才构建多页面运用。
同时,能够每一个页面都有自身的款式,因而您也能够在 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

关于竖立款式这一项,不是必需的。
末了,我们就能够运用 html-webpack-plugin 这个插件来自动天生 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 轮回天生 HTML 页面。
简朴说下 HTMLWebpackPlugin 组织函数的几个参数:

filename:天生的 HTML 文件名,我这里挑选和原始文件名保持一致
template:天生 HTML 文件运用的模板,也就是我们之前在 html 文件夹中竖立的那些文件
chunks:天生 HTML 文件时会自动插进去响应的代码片断(也就是 JavaScript 文件),我这里挑选插进去每一个页面对应的 JavaScript 文件,以及末了提取出来的大众文件代码块。
关于 chunks 还须要申明一点,chunks 是一个数组,在天生 HTML 文件时会将数组中的对应的 JavaScript 片断自动插进去到 HTML 中,这些片断也就是 webpack 打包时的 output 选项中的 [name]。这里只须要写上 [name] 值就好了,无需运用打包天生的完全称号,因为这会还没最先打包呢,打包后天生的称号咱也不知道。
末了,我们把这些天生 HTML 文件的设置插进去到 HTMLPlugins 这个数组中,同时设置 webpack 的进口文件。

目次分别

在这个脚手架中,我是如许分别项目构造的:

    ├─app
    │  ├─css
    │  ├─html
    │  ├─img
    │  ├─js
    │  └─lib
    ├─config
    └─dist
        ├─css
        ├─img
        └─js
    个中 app 是项目的源码,config 是 webpack 相干的一些设置文件,dist 是寄存打包后的文件,是由 webpack 自动天生的。
    更细致的文件构造以下:

    │  .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 进口最先实行的,我想要脚手架有以下功用:

  • 开辟环境构建
  • 临盆环境构建
  • ESLint 代码搜检环境
  • 临盆环境构建后的服务器预览环境
  • 在开辟或代码搜检环境,须要启用 webpack-dev-server 敕令,临盆环境构建须要启用 webpack 敕令,预览环境须要启用 http-server 环境。
  • 上文引见时把 http-server 给落下了,您如今能够举行以下装置:
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"
  },

下面是全部 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": {}
}

启用环境

假如您想启用某个环境,须要运用 npm run xxx 敕令:

  • npm run dev:进入开辟环境
  • npm run build:进入临盆环境
  • npm run lint:实行代码搜检
  • npm run serve:服务器环境下预览(翻开浏览器)
  • npm run serve2:服务器环境下预览(不翻开浏览器)

默许情况下,运用这些敕令都邑先引入和 package.js 同目次下的 webpack.config.js 文件。因为我们不会将一切的设置都放在 webpack.config.js 中,而是过环境变量举行辨别,在 webpack.config.js 中援用其他的设置文件。
设置环境变量采纳的语法:

set NODE_ENV=xxx
这里我们为开辟、临盆、代码搜检和预览这几个环境设置了环境变量。

  • webpack.config.js
  • webpack.config.js 文件比较简朴,只要两行代码,其作用就是用来援用其他的设置文件:
// 猎取环境敕令,并去除首尾空格
const env = process.env.NODE_ENV.replace(/(\s*$)|(^\s*)/ig,"");
// 依据环境变量援用相干的设置文件
module.exports = require(`./config/webpack.config.${env}.js`)
webpack.config.base.js

webpack.config.base.js 是最基本的设置文件,包含了这些环境都能够运用到的设置。

1)相干插件引入

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)自动天生 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 加载器

{
    // 对 css 后缀名举行处置惩罚
    test:/\.css$/,
    // 不处置惩罚 node_modules 文件中的 css 文件
    exclude: /node_modules/,
    // 抽取 css 文件到零丁的文件夹
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        // 设置 css 的 publicPath
        publicPath: config.cssPublicPath,
        use: [{
                loader:"css-loader",
                options:{
                    // 开启 css 紧缩
                    minimize:true,
                }
            },
            {
                loader:"postcss-loader",
            }
        ]
    })
},

这里有两点须要申明:
A.publicPath:在 css 中设置背景图象的 url 时,经常会找不到图片(默许会在 css 文件地点的文件夹中寻觅),这里设置 extract-text-webpack-plugin 插件的 publicPath 为图片文件夹地点的目次,就能够顺遂找到图片了。
在 config.js 中,设置 cssPublicPath 的值:

cssPublicPath:”../”
B.postcss 我重要用来自动增加 css 前缀以及一点美化操纵,在运用 postcss 时,须要在 postcss.config.js 中举行设置:

module.exports = {  
    plugins: {  
    'autoprefixer': {
        browsers: ['last 5 version','Android >= 4.0'],
        //是不是美化属性值 默许:true 
        cascade: true,
        //是不是去掉不必要的前缀 默许: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 划定了输出图片的位置,默许情况下,图片在打包时会和一切的 HTML/CSS/JS 文件打包到一同,经由过程设置 outputPath 值能够将一切的图片都打包到一个零丁的文件中。
设置 config.js 的 imgOutputPath:

imgOutputPath:”img/”,
在打包时,会将一切的图片打包到 dist 文件夹下的 img 文件夹中。

7)设置自定义字体加载器

自定义字体加载器的设置以下:

{
    test: /\.(woff|woff2|eot|ttf|otf)$/,
    use:["file-loader"]
}

8)插件设置

插件设置以下:

plugins:[
    // 自动清算 dist 文件夹
    new CleanWebpackPlugin(["dist"]),
    // 将 css 抽取到某个文件夹
    new ExtractTextPlugin(config.cssOutputPath),        
    // 自动天生 HTML 插件
    ...HTMLPlugins
],

同打包图片,在抽取 css 时也能够指定抽取的目次,只需将途径传入 extract-text-webpack-plugin 插件的组织函数中。
设置 config.js 的 cssOutputPath 选项:

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

这里将一切的 css 提取到 dist 文件夹下的 css 文件夹中,并命名为 style.css。

webpack.config.base.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:[
            {
                // 对 css 后缀名举行处置惩罚
                test:/\.css$/,
                // 不处置惩罚 node_modules 文件中的 css 文件
                exclude: /node_modules/,
                // 抽取 css 文件到零丁的文件夹
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    // 设置 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:[
        // 自动清算 dist 文件夹
        new CleanWebpackPlugin(["dist"]),
        // 将 css 抽取到某个文件夹
        new ExtractTextPlugin(config.cssOutputPath),        
        // 自动天生 HTML 插件
        ...HTMLPlugins
    ],
}

webpack.config.dev.js

这个设置文件重要用来在开辟环境运用,须要 webpack-dev-server 这个插件供应支撑。该文件的设置以下:

// 引入基本设置文件
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:{
        // 项目根目次
        contentBase:config.devServerOutputPath,
        // 毛病、正告展现设置
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

个中,webpack-merge 这个插件用来对设置文件举行兼并,在 webpack.config.base.js 的基本上兼并新的设置。
devServer 设置项的 contentBase 项是项目的根目次,也就是我们的 dist 目次,辨别在于这个 dist 目次不是硬盘上的 dist 目次,而是存在于内存中的 dist 目次。在运用 webpack-dev-server 时,将会以这个内存中的 dist 目次作为根目次。
devServer 的 overlay 选项中设置了展现毛病和正告,如许当代码发作毛病时,会将毛病信息投射到浏览器上,轻易我们开辟。
这里将 contentBase 指向了 config 中的一个设置:

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

该设置文件用来在临盆环境启用,重要用来紧缩、兼并和抽取 JavaScript 代码,并将项目文件打包至硬盘上的 dist 文件夹中。

// 引入基本设置
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 代码时,我们将大众代码抽取为 commons.bundle.js,这个大众代码的 chunk(name)名就是 commons,在运用 html-webpack-plugin 自动天生 HTML 文件时会援用这个 chunk。

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$/,
                // 强迫先举行 ESLint 搜检
                enforce: "pre",
                // 不对 node_modules 和 lib 文件夹中的代码举行搜检
                exclude: /node_modules|lib/,
                loader: "eslint-loader",
                options: {
                    // 启用自动修复
                    fix:true,
                    // 启用正告信息
                    emitWarning:true,
                }
            },
        ]
    },
    devServer:{
        contentBase:config.devServerOutputPath,
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

在运用 eslint-loader 时,我们设置了 enforce:”pre” 选项,这个选项示意在处置惩罚 JavaScript 之前先启用 ESLint 代码搜检,然后再运用 babel 等 loader 对 JavaScript 举行编译。
在 eslint-loader 的 options 选项中,设置了自动修复和启用正告信息,如许当我们的代码出现题目时,ESLint 会起首尝试自动修复(如将双引号改成单引号),关于没法自动修复的题目,将以正告或毛病的信息举行展现。

设置 .eslintrc.js

要想运用 ESLint 举行代码搜检,除了运用 eslint-loader 以外,还需针对 ESLint 自身举行设置,这就须要一个 .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'],
        //是不是美化属性值 默许:true 
        cascade: true,
        //是不是去掉不必要的前缀 默许: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

// 猎取环境敕令,并去除首尾空格
const env = process.env.NODE_ENV.replace(/(\s*$)|(^\s*)/ig,"");
// 依据环境变量援用相干的设置文件
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:[
            {
                // 对 css 后缀名举行处置惩罚
                test:/\.css$/,
                // 不处置惩罚 node_modules 文件中的 css 文件
                exclude: /node_modules/,
                // 抽取 css 文件到零丁的文件夹
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    // 设置 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:[
        // 自动清算 dist 文件夹
        new CleanWebpackPlugin(["dist"]),
        // 将 css 抽取到某个文件夹
        new ExtractTextPlugin(config.cssOutputPath),        
        // 自动天生 HTML 插件
        ...HTMLPlugins
    ],
}

webpack.config.dev.js

// 引入基本设置文件
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:{
        // 项目根目次
        contentBase:config.devServerOutputPath,
        // 毛病、正告展现设置
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

webpack.config.prod.js

// 引入基本设置
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$/,
                // 强迫先举行 ESLint 搜检
                enforce: "pre",
                // 不对 node_modules 和 lib 文件夹中的代码举行搜检
                exclude: /node_modules|lib/,
                loader: "eslint-loader",
                options: {
                    // 启用自动修复
                    fix:true,
                    // 启用正告信息
                    emitWarning:true,
                }
            },
        ]
    },
    devServer:{
        contentBase:config.devServerOutputPath,
        overlay:{
            errors:true,
            warnings:true
        }
    }
});

项目构造

│  .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而不是每一个页面都援用只须要:

引入jquery后假如开启lint搜检形式 能够一般运用的条件是每一个页面都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",
        // 设置 css 的 publicPath
        publicPath: config.cssPublicPath,//在 css 中设置背景图象的 url 时,经常会找不到图片(默许会在 css 文件地点的文件夹中寻觅),这里设置 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这类库函数 但不处置惩罚modules内里的swiper,所以这里要许可除了node_modules内里的swiper的其他一切文件

  • webpack.config.base.js
{
    test: /\.js$/,
    exclude: /^node_modules*swiper$/, 
    use: {
        loader: 'babel-loader',
        options: {
            presets: ['env']
        }
    }
},

github地点:点我

    原文作者:不会飞的Porco
    原文地址: https://segmentfault.com/a/1190000017565103
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞