Webpack配置总结(持续更新中)

Webpack 4x配置总结

Webpack

概念

一种模块打包机,视HTML,JS,CSS,图片等文件都是一种 资源 ,每个资源文件都是一个模块(module)文件,webpack就是根据每个模块文件之间的依赖关系将所有的模块打包(bundle)起来。

作用

对 CommonJS 、 AMD 、ES6的语法做了兼容

对js、css、图片等资源文件都支持打包(适合团队化开发)

比方你写一个js文件,另外一个人也写一个js文件,需要合并很麻烦,现在交给webpack合并很简单

有独立的配置文件webpack.config.js

可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间

具有强大的Plugin(插件)接口,大多是内部插件,使用起来比较灵活

认识

核心概念分为 入口(Entry)、加载器(Loader)、插件(Plugins)、出口(Output)

入口(Entry)

入口起点告诉 webpack 从哪里开始,并根据依赖关系图确定需要打包的文件内容

加载器(Loader)

webpack 将所有的资源(css, js, image 等)都看做模块,但是 webpack 能处理的只是 JavaScript,因此,需要存在一个能将其他资源转换为模块,让 webpack 能将其加入依赖树中的东西,它就是 loader。

loader用于对模块的源代码进行转换。loader 可以使你在 import 或”加载”模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。

插件(Plugins)

loader 只能针对某种特定类型的文件进行处理,而 plugin 的功能则更为强大。在 plugin 中能够介入到整个 webpack 编译的生命周期,Plugins用于解决 loader 无法实现的其他事情,也就是说loader是预处理文件,那plugin 就是后处理文件。

对loader打包后的模块文件(bundle.js)进行二次优化处理,例如:代码压缩从而减小文件体积

提供辅助开发的作用:例如:热更新(浏览器实时显示)

出口(Output)

打包后的js,如

output: {
    filename: "bundle.js",
    path: path.join(__dirname, '../dist'),
},

源码

注:以react-musicplayer-simple工程为例

package.json

{
  "name": "react-musicplayer-simple",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config build/webpack.config.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-es2015-loose": "^8.0.0",
    "babel-preset-react": "^6.24.1",
    "cross-env": "^5.2.0",
    "css-loader": "^1.0.0",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.2.0",
    "jplayer": "^2.9.2",
    "jquery": "^3.3.1",
    "json-loader": "^0.5.7",
    "less": "^3.8.1",
    "less-loader": "^4.1.0",
    "react-hot-loader": "^4.0.0",
    "style-loader": "^0.22.1",
    "url-loader": "^1.0.1",
    "webpack": "^4.16.5",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.5"
  },
  "dependencies": {
    "pubsub-js": "^1.6.0",
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1"
  }
}

Webpack.config.js

const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')
const isDev = process.env.NODE_ENV === 'development'
const webpack = require('webpack')

const config = {
    entry: {
        app: path.join(__dirname, '../client/index.js')
    },
    output: {
        filename: "bundle.js",
        path: path.join(__dirname, '../dist'),
    },
    module: {
        rules: [
            {
                test: /.jsx$/,
                loader: 'babel-loader',
            },
            {
                test: /.js$/,
                loader: 'babel-loader',
                exclude: [
                    path.join(__dirname, '../node_modules')
                ]
            },
            {
                test: /.less$/,
                loader: ["style-loader","css-loader","less-loader"]
            },
            {
                test: /.css$/,
                loader: ["style-loader","css-loader"]
            },
            {
                test: /.(png|jpg)$/,
                loader: "url-loader",
                options: {
                    limit: 10000,
                    name: 'static/media/[name].[hash:8].[ext]'
                }
            },
            {
                test: /\.(mp3)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    name:'static/media/[name].[ext]',
                    limit:10
                }
            }
        ]
    },
    plugins: [
        new HTMLPlugin({
            template: path.join(__dirname, '../client/index.tp.html'),
            inject:'body',
            filename:'./index.html'
        })
    ]
}


//localhost:8888/filename
if (isDev) {
    config.entry = {
        app: [
            'react-hot-loader/patch',
            path.join(__dirname, '../client/index.js')
        ]
    }
    config.devServer = {
        host: 'localhost',
        port: '8888',
        contentBase: path.join(__dirname, '../dist'),
        hot: true,
        overlay: {
            errors: true
        },
        publicPath: '/public',
        historyApiFallback: {
            index: '/public/index.html'
        }
    }
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
}

module.exports = config

.babelrc

{
  "presets": [
    ["es2015", { "loose": true}],
    "react"
  ],
  "plugins": ["react-hot-loader/babel"]
}