使用 webpack3 配置多页应用(二)

在本系列文章的基础上,我对脚手架配置进行了一些优化整理,基于 Webpack4 和 Vue,下面是文章链接:
基于 Webpack4 + Vue 的多页应用解决方案(一)
基于 Webpack4 + Vue 的多页应用解决方案(二)


上篇文章,主要谈到了使用 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

如果将全部文件都列出来的话,太长了,不忍直视,因此我把文件的内容精简了一些:)
其中 .babrlrc 是 babel 的相关配置文件,.eslintrc.js 是 ESLint 相关的配置文件,.gitignore 是 git 仓库上传时的忽略项目,postcss.config.js 是 postcss 相关的配置。

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.js 和 webpack.config.base.js 文件的配置,鉴于篇幅,将剩下的配置文件放在后文进行介绍。

完。

你可能感兴趣的:(使用 webpack3 配置多页应用(二))