首先我们先建立这样的目录
文件说明:
src : 放置源文件的目录
dist : 放置打包后文件的目录
index.html : 初始化页面(要手动引用生成的js文件)
entry.js : 入口js文件
entry2.js : 入口js文件
webpack.config.js : webapck的配置文件
webapck的配置文件, (具体的配置在文档 API—>configuration )为何建立webpack.config.js ,是因为在命令行中执行webpack会默认寻找目录下的webpack.config.js,以webpack.config.js的配置去运行。
当然也可以webpack --config hcd.js 执行hcd.js中的配置
webpack.config.js的基本结构
module.exports={
//当前环境设置
mode: 'production',
//入口文件的配置项
entry:{
},
//出口文件的配置项
output:{
},
//模块:例如解读CSS,图片如何转换,压缩
module:{
},
//插件,用于生产模版和各项功能
plugins:[],
//配置webpack开发服务功能
devServer:{
}
}
入口配置和出口配置:
//模块化输出
module.exports = {
mode: 'development',
//入口文件,一般使用绝对路径,__dirname为webpack.config.js所在的文件夹
entry:__dirname+'/src/entry.js',
// 打包后的文件
output:{
//打包后文件在./dist/js的文件夹中
path:__dirname+'/dist/js',
//打包后文件的名称
filename:'bundle.js'
}
}
再在命令行中执行 webpack 命令:
结果目录为:
我们可以看到已经自动打包生成了dist文件夹和bundle.js
mode
配置选项将告诉webpack
相应地使用其内置优化。
mode在配置中提供选项:
module.exports = {
mode: 'development'
};
在命令行中或者package.json中
webpack --mode=development
选项 | 描述 |
---|---|
development | 设置 process.env.NODE_ENV 于 DefinePlugin 价值 development 。启用 NamedChunksPlugin 和 NamedModulesPlugin 。 |
production | 设置 process.env.NODE_ENV 于 DefinePlugin 价值 production 。启用 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 TerserPlugin 。 |
none | 选择退出任何默认优化选项 |
如果未设置,则webpack设置production为的默认值mode
请记住,设置NODE_ENV不会自动设置mode。需要自己设置
如果要根据webpack.config.js中的mode变量更改行为,则必须导出函数而不是对象:
var config = {
entry: './app.js'
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};
在上面的例子中,我们已经知道,entry是入口文件的意思,webpack关于入口文件有3种方式
API:http://webpack.github.io/docs/configuration.html#entry
entry: "./src/js/main.js",
entry:['./src/js/main.js','./src/js/hello.js']
可以看到一共打包了【0】【1】【2】3个模块,【0】是multi,【1】,【2】才是我们想要打包的内容,这是为何呢,我们来看一下打包后的文件bundle.js
可以看到其实【0】模块是用来引用我们的【1】【2】模块的,将【1】【2】打包到一起去,这样我们就可以使用了
这种传递entry对象的方式多应用于多页面, chunk:path(模块:路径)
page1页面使用”./page1“打包后的文件,page2页面使用的是["./entry1", “./entry2”]打包后的文件
entry: {
page1: "./page1",
page2: ["./entry1", "./entry2"]
},
但是如果不更改output将会导致两个文件打包后输出的文件名字一样,造成了重复覆盖,所以要更改output
API:http://webpack.github.io/docs/configuration.html#output
影响编译输出的选项。output选项告诉Webpack如何将编译的文件写入磁盘。请注意,虽然可以有多个entry点,但output只指定一个配置。
指定磁盘上每个输出文件的名称。你不能在这里指定绝对路径!该output.path选项确定磁盘上写入文件的位置。filename仅用于命名单个文件。
单个入口文件:
{
mode: 'development',
entry: './src/app.js',
output: {
filename: 'bundle.js',
path: __dirname + '/build'
}
}
如果您的配置创建多个单个“块”(如多个入口点或使用像CommonsChunkPlugin这样的插件),则应使用替换来确保每个文件具有唯一的名称。
[name] 被块的名称所取代。(就是entry对象的chunk)
[hash] 被编译的哈希替换。(在编译的时候可以看到)
[chunkhash] 被块的哈希替代。(块的哈希值如同MD5一样,只要代码不一样,哈希就不同)
{
mode: 'development',
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/build'
}
}
例如:
//模块化输出
module.exports = {
mode: 'development',
//入口文件,这里采用entry对象的方式,分别将main.js和hellow.js打包
entry:{
main:'./src/script/main.js',
hello:'./src/script/hellow.js'
},
// 打包后的文件
output:{
//打包后文件在./dist/js的文件夹中
path:__dirname+'/dist/js',
//打包后文件的名称为entry的chunk名称-编译的哈希值
filename:'[name]-[hash].js'
}
}
编译过程:
可以看到打包成了两个文件 (因为编译的哈希一样所以后面的是一样的)
当然可以采用【name】-【chunkhash】这样产生的文件名就完全不一样了,【chunkhash】就如同是MD5一样,是完全不同的,哪怕是同一个js只要代码发生变化【chunkhash】就会不同,这是非常有用的,我们一般只上线我们更改的js文件。
输出目录为绝对路径(必需)。
现在一般有点规模的公司都为前端工程师准备了双屏显示器,其目的就是一个屏幕编写代码,一个屏幕实时显示页面效果。下面我们用webpack3.6版本实现热更新效果。
设置webpack-dev-server
首先利用npm 下载(现在的webpack的高版本中已经自带,可以不用下载,你可以先不下载,先试一下有没有)
npm install webpack-dev-server --save-dev
下载好后,需要配置一下devServer。最简单的devServer配置项只有 4项
wepack.config.js :
var path = require('path');
module.exports = {
mode: 'development',
//入口文件的配置项
entry: {
//entry和addNew为打包后文件的名称
entry: __dirname + '/src/entry.js',
//这里我们又引入了一个入口文件
addNew: __dirname + '/src/entry2.js'
},
//出口文件的配置项
output: {
//输出的路径
path: __dirname + "/dist",
//输出的文件名称
filename: '[name].js'
},
devServer:{
//设置基本目录结构
.join(__dirname, 'dist'),,
//服务器的IP地址,可以使用IP也可以使用localhost
host:'localhost',
//服务端压缩是否开启
compress:true,
//配置服务端口号
port:1717
}
}
接着我们执行命令:
webpack-dev-server
结果:
我们看到文件已经打包完成了,但是在dist目录里并没有看到文件,这是因为WDS是把编译好的文件放在缓存中,没有磁盘上的IO,但是我们是可以访问到的
http://localhost:1717/【打包后的文件名】
配置告知 webpack-dev-server,在 localhost:1717下建立服务,将 dist 目录下的文件,作为可访问文件,所以我们可以直接输入打包后的文件名的地址查看
如果找不到文件可以通过http://localhost:1717/webpack-dev-server
查找
问题:
配置好后,你可以试着在终端中输入webpack-dev-server,如果可以执行成功,但是往往提示错误(或者是无法找到内部或外部命令)。我们可以在json中配置解决问题
首先目录和前面是一样的,webapck.config.js的配置也是一样的。
只不过可以通过在package.jsond的script中设置便捷的执行命令的方式。
{
"name": "webpack-hcd",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"webpack":"webpack --config webpack.config.js --mode=development --progress --display-modules --colors",
"server": "webpack-dev-server --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.6.0"
}
}
解释:
"webpack":"webpack --config webpack.config.js --progress --display-modules --colors"
webpack --config webpack.config.js : 执行webpack.config.js
–progress : 查看过程
–display-modules : 打包了哪些模块
–colors : 彩色的
–open : 自己打开页面
执行命令行:
npm run webpack
执行热更新命令
npm run server
webpack-dev-server
的更新是需要刷新整个页面的,有时我们需要局部刷新,这就有了模块热替换
特性:
模块热替换(HMR - Hot Module Replacement
)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:
启用
启用HMR
,其实十分简单,修改下webpack-dev-server
的配置,和使用webpack
内置的HMR
插件即可。
var path = require('path');
// 新增
var webpack = require('webpack');
module.exports = {
entry: {
entry: __dirname + '/src/entry.js',
},
output: {
path: __dirname + "/dist",
filename: '[name].js'
},
devServer:{
contentBase:path.join(__dirname, 'dist'),
host:'localhost',
compress:true,
port:1717,
// 新增
hot: true
},
// 新增
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
entry.js
import {
test } from './hcd.js'
let a = 1;
console.log(a);
test()
hcd.js
module.exports = {
test: function () {
console.log(11121231212312333456)
}
}
启动
npm run server
访问:
http://localhost:1717/bundle