webpack 从开始到结束

教你从零开始写一个简单的webpack打包配置

这篇文章的全部代码已经上传到github。有需要的童鞋可以去看看。
github.com/Link-X/webp… 先简单看一下我们这个教程最终的文件结构

主要就是这个webpack.config.prod.js 和 webpack.config.js。这两是全部的webpack配置

正文开始-------

千里之行始于足下。首先我们先新建一个文件夹,简单点就叫pack吧

打开这个文件夹,此时文件夹里什么都没有

第一步:需要一个 package.json的文件。

我们通过yarn init(npm init也行) 命令行初始化一个。

如果你没有按照yarn或者npm的话去先去安装一个。这里就不细说了,这里推荐yarn。
1、npm安装方式:直接下载一个node,它自带npm。。
2、yarn安装方式:yarn安装教程点这个教程很详细。

安装完后输入 yarn init 不出意料会出现这些东西,项目名称、版本、说明、协议、存储地址等等

一步步确认下来后,pack文件夹就会出现一个 package.json的文件
打开这个package.json 这里面就是我们刚刚输入的东西。这是一个配置文件,主要是配置我们项目需要的包的。是一个纯json
我们先不管管它(^_^)

第二步:安装依赖,首先安装这两个 webpack、webpack-cli

yarn add webpack webpack-cli -D

或者
yarn add webpack -D

yarn add webpack-cli -D

这时有同学会问,这个 yarn add *** -D 是啥意思呀,后面那个-D又是什么鬼。好 我们简单解释一下这条命令,这条命令的意思就是把 webpack、webpack-cli 这两个第三方插件添加到开发时依赖。也就是说虽然我们安装了这两个包,但是我们只是希望在开发的时候使用它们,生产环境的代码可别有它们的身影。-D是--save-dev的简写, 意思安装的包到开发环境依赖。最终webpack 打包的时候会去读取 package.json。然后通过它会知道哪些是开发依赖,哪些是生产依赖。当然还有很多别的。这里只是简单介绍一下

打开 package.json,发现里面多了一个devDependencies, 刚刚我们add的哪两个开发依赖就在这里。

细心的同学可能已经发现,文件里还多了一个 node_modules的文件夹。打开一看,发现里面多了一大堆乱七八糟的东西。电脑配置不高的童靴光是把它删除就可能就要卡一两分钟,当然你千万别测试电脑性能删了它(ememem~~!)。

为什么这个文件这么大腻,咱们只是安装了两个插件而已。这因为我们安装的这两个东西它也有他自己的依赖。它的依赖又可能依赖了别的依赖。如此循环~~ 啊哈哈。

这只是一个简单的解释。它里面还有一些特殊的文件夹。比如.bin 这是存放一些命令的文件。

说到这个.bin 那么,童靴们接下来我们要搞一些事情。
首先在pack文件夹下,我们新建一个 src文件。在src文件下又新建一个 index.js,里面什么都不写
再打开刚刚生成的package.json。在里面新增一条数据。

"scripts": {
    "build": "webpack --mode production"
 }
复制代码

然后,在控制台执行 yarn build

卧槽什么情况。没错,是的此时以你已经精通webpack。变身 webpack 配置大失。

是不是很简单。啊哈哈哈~~~。就是这么简单!

嘿嘿,好啦,其实这只是一个开始,刚刚说到.bin文件夹,解释一下我们新增的再package.json 里的 scripts,里面的命令 就是在执行的时候自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令,比如 yarn build,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。

第三步: 自定义配置webpack 配置

刚刚的操作并不能完成我们日常的需求,接下来我教大家如何,自定义配置webpack。首先我们新建一个 webpack.config.js 文件

当我们执行打包命令的时候,webpack会默认读取这个文件。获取用户自定义的配置。这个配置文件本质上是一个node的脚本,所以灵活性比较高

首先是入口(entry):入口是什么?webpack 的入口就是 从这个文件开始,以这里为起点开始依赖的所以东西全部打包。像一条线把你的代码连起来。

// module.exports 是node默认支持的CMD模块语法,我们这里的意思就是导出一个字面量对象,让webpack读取来当它的配置。详细可以自行搜索CMD模块
module.exports = {
    // 这是单入口的配置写法
    entry: './src/index.js'
}
module.exports = {
  // 这是多入口的写法
  entry: {
    foo: './src/top.js',
    bar: './src/bottom.js', 
    // ...
  }
}
复制代码

然后出口(output):
啥是出口,顾名思义,就是指 webpack 最终构建出来的静态文件

// 有童鞋问着个path.resolve(__dirname, 'dist')是啥呀。
// path.resolve() 如果有参数 返回这个参数相对于当前的工作目录的绝对路径
// __dirname 这个也是node的一个api,意思是这个被执行的文件的绝对路径
// path.resolve(__dirname, 'dist')返回当前工作目录被执行文件(webpack.config.js)的绝对路径的下的dist。
// 总之咱么这就是返回 pack下dist 在你电脑的绝对路径
const path = require('path')
module.exports = {
    ...
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
    }
}
复制代码

在然后是loader:
啥loader? 刚刚我们说了 webpack会从入口开始把你的代码连起来,连起来然后呢?烤了吃?^_^ 当然不是。webpack会通loader 把他们都转换了。转换它干啥?为啥要转换。我写的代码这么吊,还需要转换么...
开个玩笑,当然要转换。loader的目的就是转换你的代码,比如 我们知道css 有些属性还处于实验阶段,需要你加入一个前缀浏览器才回去识别他们,如 --ms-- --webkit-- 。
还有js 有些新api 特性等 浏览器厂商可能还没实现。咋办呢,咱么通过loader 转换一下就可以把我们自己写的新代码,让没有它可以在浏览器上执行。
还有less sass 等浏览器天生并不能能识别它们。需要一个转换。

module.exports = {
    ...
    ...
    module: {
        rules: [
            {
                test: /\.js$/, // 需要转换的文件,这里用正则匹配所以.js文件
                loader: 'babel-loader', // 指定用到的那个loader去转换
                include: [path.resolve(__dirname, 'src')] // 指定loader从哪里转换文件
            }
        ]
    },
}
复制代码

对了,这个 babel-loader 还需要一个单独的配置文件。别方,我们简单配置一下即可。 pack 目录下新建一个 .babelrc 文件

里面写

{
    "presets": ["es2015", "stage-2"],
    "plugins": []
}
复制代码

babel-loader 是个第三方插件,我们需要安装一下,只需要在开发环境依赖即可
yarn add babel-loader babel-cli babel-preset-es2015 babel-preset-stage-2 -D

然后是plugins:
plugins 是啥?plugins 就是除了loader之外的所以事,都是plugins做,比如压缩代码什么的。

const UglifyPlugin = require('uglifyjs-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    ...
    ...
    ...
    plugins: [
        new UglifyPlugin(), // 压缩文件
        new HtmlWebpackPlugin({
            filename: 'index.html', // 配置输出文件名和路径
            minify: { // 压缩 HTML 的配置
                minifyJS: true // 压缩 HTML 中出现的 JS 代码
            }
        })
    ]
}
复制代码

这里我们也需要安装一下uglifyjs-webpack-plugin 、 html-webpack-plugin ,两个分别是压缩文件的,和帮我们生成一个index.html的,两个都是开发依赖
yarn add uglifyjs-webpack-plugin -D
yarn add html-webpack-plugin -D

最后我们再说一个resolve 配置:

module.exports = {
    ...
    ...
    ...
    ...
    resolve: {
        extensions: [".wasm", ".mjs", ".js", ".json"], // 查找文件顺序
        alias: {
            "@": path.resolve(__dirname, 'src') // 路径别名,以后导入模块,前面加一个@就是当如src下的xxx
        }
    }
}
复制代码

引入的时候有时候我们会省略后缀,不如后面那个.js .html 这个 extensions 就是配置webpack 用那个后缀优先查找文件. alias 的意思就是配置一个路径别名,用过vue的人应该比较熟悉这个。 如

import test from '@/test/index.js'
复制代码

就是导入当前目录src下的test/index.js

在提一下通过es6或者cmd 模块引入一个模块,首先会去找是否当前目录,当前没目录没有会去找上级,最后到根目录,如果还是没有就会找node_module 。要是还是没找到就报错.

最后我们的完整配置就是

// webpack.config.js
const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
    },
    module: {
        rules: [{
            test: /\.js$/, // 用 babel-loader 解析js
            loader: 'babel-loader',
            include: [path.resolve(__dirname, 'dist')]
        }]
    },
    plugins: [
        new UglifyPlugin(), // 压缩文件
        new HtmlWebpackPlugin({
            filename: 'index.html', // 配置输出文件名和路径
            minify: { // 压缩 HTML 的配置
                minifyJS: true // 压缩 HTML 中出现的 JS 代码
            }
        })
    ],
    resolve: {
        extensions: [".wasm", ".mjs", ".js", ".json"], // 查找文件顺序
        alias: {
            "@": path.resolve(__dirname, 'src') // 路径别名,以后导入模块,前面加一个@就是当如src下的xxx
        }
    }
}
复制代码

我们在src/index.js下写一行 console.log(1) 然后执行一下 yarn build

打包成功. 打开dist/index.html

没错熟悉的味道.

然后是热更新,这块我也不是很熟悉。简单贴一下配置吧,

pack下新建一个config文件夹,然后新建一个server.js

里面写

const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require("webpack-hot-middleware")
const webpackOptions = require('../webpack.config.js')
const path = require('path')

webpackOptions.mode = 'development'
const compiler = webpack(webpackOptions),
  express = require('express'),
  app = express(),
  DIST_DIR = path.join(__dirname, '..', 'dist')

const devMiddleware = webpackDevMiddleware(compiler, {
  publicPath: webpackOptions.output.publicPath,
  quiet: true
})
const hotMiddleware = webpackHotMiddleware(compiler, {
  log: false,
  heartbeat: 2000
})


app.use(devMiddleware)
app.use(hotMiddleware)

app.listen(3000, () => console.log('http://localhost:3000'))
复制代码

然后需要安装一下三个需要用的的热更新的插件
yarn add webpack-dev-middleware webpack-hot-middleware express -D

在webpack.config.js 改三个小小的地方.

// 1、新增导入 webpack
const webpack = require('webpack')
// 2、入口改成这样
 entry: {
        main: ['webpack-hot-middleware/client.js?reload=true', './src/index.js']
 }
 // 3、plugins 改成这样
plugins: [
    new UglifyPlugin(), // 压缩文件
    new HtmlWebpackPlugin({
        filename: 'index.html', // 配置输出文件名和路径
            minify: { // 压缩 HTML 的配置
                minifyJS: true // 压缩 HTML 中出现的 JS 代码
            }
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin()
    ]
 //

复制代码

最后在 package.json 的scripts 加入"start": "node config/server.js"

// 如下
{
 "name": "packTest",
 "version": "0.01",
 "description": "webpack初体验",
 "main": "index.js",
 "license": "MIT",
 "scripts": {
   "start": "node config/server.js",
   "build": "webpack --mode production"
 },
 "devDependencies": {
   "babel-loader": "^8.0.4",
   "express": "^4.16.4",
   "html-webpack-plugin": "^3.2.0",
   "uglifyjs-webpack-plugin": "^2.0.1",
   "webpack": "^4.25.1",
   "webpack-cli": "^3.1.2",
   "webpack-dev-middleware": "^3.4.0",
   "webpack-hot-middleware": "^2.24.3"
 }
}

复制代码

yarn start .启动啦 访问 http://localhost:3000/

成功,随便修改src/index.js 下任意代码就可以看到也没自动刷新了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值