命令使用
npm install webpack -g
作为全局安装, 在任意目录使用
npm install webpack --save-dev
作为项目依赖安装
npm init
创建package.json
npm install webpack-dev-server --save-dev
使用webpack-dev-server启动服务器
webpack --progress -colors
让编译的输出内容带有进度和颜色
webpack --watch
如果不想每次修改模块后都重新编译, 那么可以启动监听模式。
开启监听模式后, 没有变化的模块会在编译后缓存到内存中,
而不会每次都被重新编译, 所以监听模式的整体速度是很快的
webpack --display-error-details
用来打印错误详情
npm install xxx-loader --save-dev
安装多个加载器: npm install babel-core babel-preset-es2015 babel-preset-react
npm webpack --config webpack.config.js
执行打包命令
npm start
启动开发模式下的server
npm run start:prod
启动生产模式的server
npm run build
打包生产模式的代码
npm run lint: eslint
代码检查
npm run lint:watch: eslint
监视
npm run remove:build
删除dist目录
npm run clean:build
清除dist目录
// 调用webpack
webpack
开发环境下编译
webpack -p
产品编译及压缩
webpack --watch
开发环境下持续的监听文件变动来进行编译
webpack -d
引入source maps
配置文件
webpack.config.dev.js: 开发模式相关配置
webpack.config.prod.js: 生产模式相关配置
server.js: 配置本地的server(包含dev server和prod server) 将server部分分离到一个单独到的文件配置
package.json
//webpack.config.dev.js
var webpack = require('webpack');
var path = require('path');
var config = {
// 入口文件配置
entry: {
path.resolve(__dirname, 'app/index.js');
},
// 文件输出配置
output: {
path: path.resolve(_dirname, 'build'),
filename: 'bundle.js',
publicPath: '/'
},
// 插件项
plugins: [],
// 加载器配置
module: {
loaders: [
{
test: /pattern/,
loader: 'xxx-loader',
exclude: /dir/,
query: {
presets: ['react']
}
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
// 内联的base64的图片地址, 图片要小于8k, 直接的url的地址则不解析
}
]
},
// 其他解决方案配置
resolve: {
extensions: ['', '.js', '.json'],
alias: {}
},
watch: true
};
module.exports = config;
webpack.server.js
var webpack = require('webpack');
var webpackServer = require('webpack-dev-server');
var config = require('./webpack.config.dev.js');
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
contentBase: './app',
historyApiFallback: true,
hot: true, //热启动
inline: true, // 监控js变化
stats: {
color: true
}
});
config.entry.unshift('webpack-dev-server/client?http://localhost:8080/',
'webpack/hot/dev-server');
server.listen(8080, 'localhost', function(err) {
if(err) {
console.log(err);
}
console.log('Listening at localhost:8080...');
});
<!-- package.json -->
'script': {
'start': 'node server.js'
}
配置详解
entry: 入口, 定义要打包的文件
output: 出口, 定义打包输出的文件;包括路径, 文件名,还可能有运行时的访问路径(publicPath)参数
module: webpack将所有的资源都看做是模块, 而模块就需要加载器;
|---- loaders: 主要定义一些loaders, 定义哪些后缀名的文件应该用哪些loader
|-------- test: 匹配文件后缀, 检测哪些文件需要此loader, 是一个正则表达式
|-------- exclude: 忽略哪些文件
|-------- query: 参数 (或直接写于loader如: loader: 'url-loader?limit=8192')
|------------ presets:
resolve: 其他解决方案配置
|---- extensions: 忽略文件扩展名, require文件时可直接使用require('file'),而非带后缀如require('file.js')
|-------- alias: 模块别名定义,方便后续直接饮用别名无需多写长地址, 后续直接require(key)
plugins: 定义一些额外的插件
watch: 值为boolean, 监听文件变化
配置生产环境
开发环境:
webpack.config.dev.js
需要日志输出, sourcemap, 错误报告等
生产环境:
webpack.config.prod.js
需要做代码压缩, 对文件名进行hash处理等
区分环境
使用DefinePlugin设置环境变量, 根据设置的环境变量决定是否打包压缩及启动dev server或prod server
plugins: [
new webpack.DefinePlugin({
'process.evn.NODE_ENV': JSON.stringify('production')
});
]
判断当前是否是生产环境
var isProduction = function() {
return process.env.NODE_ENV === 'production';
}
output: {
path: path.resolve(isProduction ? '__build' : './assets/'),
filename: isProduction ? '[name].js' : './assets/js/[chunkhash:8].[name].min.js',
chunkFilename: isProduction ? '[chunkhash:8].chunk.js' : './assets/js/[chunkhash:8].chunk.min.js',
publicPath: isProduction ? '/__build/' : 'http://cdn.site.com/'
}
代码压缩
new webpack.optimizeUglifyJsPlugin({
compress: {
warnings: false
}
});
添加Hash缓存
对于没有修改的文件, 从缓存中获取文件, 对于已经修改的文件, 不要从缓存中获取
output: {
//chunkhash 默认16位, 可自定义配置
filename: '[chunkhash:8].bundle.js'
}
自动生成页面
文件名带上hash值后, 这个值在每次编译的时候都会发生变化,都需要在 html 文件里手动修改引用的文件名,这种重复工作很琐碎且容易出错, 这里我们可以使用 html-webpack-plugin 来帮我们自动处理这件事情, 用来简化创建服务于webpackbundle的HTML文件
解决方案: 在项目目录下建一个index.tpl.html作为钩子
<!-- index.tpl.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My APP</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
在webpack.config.dev.js和webpack.config.prod.js添加配置代码, 即可生成相应的index.html
plugins: [
new HtmlWebpackPlugin({
template: 'app/index.tpl.html',
inject: 'body',
filename: index.html
})
]
加载器
js处理
babel-loader: 转换JSX
babel-core: babel核心包
babel-preset-react
babel-preset-es2015
<!-- webpack.config.dev.js -->
<!-- babel-loader配置 -->
loaders:[
{
loaders: 'xxx-loader',
query: {
resets:['react', 'es2015']
}
}
]
css处理
style-loader
css-loader
less-loader
img处理
url-loader
可以根据自定义文件大小或者转化为 base64 格式的 dataUrl, 或者单独作为文件, 也可以自定义对应的hash 文件名
file-loader
默认情况下会根据图片生成对应的 MD5hash 的文件格式
image-webpack-loader
提供压缩图片的功能
加载babel-loader需要配置query参数
<!-- webpack.config.dev.js -->
<!-- url-loader配置 -->
loaders:[
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
// 当内容size小于8KB时, 会自动转成base64的方式内嵌进去, 这样可以减少一个HTTP的请求
// 当图片大于8KB时, 则会在img/下生成压缩后的图片, 命名是[hash:8].[name].[ext]的形式
// hash:8的意思是取图片内容hashsum值的前8位,
// 这样做能够保证引用的是图片资源的最新修改版本, 保证浏览器端能够即时更新
'url?limit=8192&name=img/[hash:8].[name].[ext]',
// 图片压缩
'image-webpack'
]
}
]
<!-- webpack.config.dev.js -->
<!-- file-loader配置 -->
loaders:[
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
// 生成md5 hash格式的文件名
'file?hash=sha512&digest=hex&name=[hash].[ext]',
// 图片压缩
'image-webpack'
]
}
]
插件
<!-- webpack.config.dev.js -->
plugins: [definPlugin, bannerPlugin, uglifyJsPlugin...]
设置环境变量
var definPlugin = new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
// feature flags: 在开发环境(例如日志)活内部测试环境(例如没有发布的新功能)中使用
// __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
// __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false'))
});
给输出的文件头部添加注释信息
var bannerPlugin = new webpack.BannerPlugin('This is test!');
JS混淆
var uglifyJsPlugin = new webpack.optimize.UglifyJsPlugin({
mangle: {
// 配置以下列表, 在混淆代码时, 以下配置的变量, 不会被混淆
except: ['$super', '$', 'exports', 'require']
}
});
压缩JS
var minChunkSizePlugin = new webpack.optimize.MinChunkSizePlugin({
compress: {
warnings: false
}
});
压缩React
var definPlugin = new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
});
加载jQuery
new webpack.ProvidePlugin({
$: 'jquery'
});
公共模块提取
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors', // 将公共模块提取, 生成名为`vendors`的chunk
chunks: ['index','list','about'], //提取哪些模块共有的部分
minChunks: 3 // 提取至少3个模块共有的部分
});
单独使用link标签加载css并设置路径
new ExtractTextPlugin('css/[name].css'), // 相对于output配置中的publickPath
自动生成html文件, 模板生成的相关配置, 每个对于一个页面的配置, 有几个写几个
new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
favicon: './src/img/favicon.ico', //favicon路径, 通过webpack引入同时可以生成hash值
filename: './view/index.html', //生成的html存放路径, 相对于path
template: './src/view/index.html', //html模板路径
inject: 'body', //js插入的位置, true/'head'/'body'/false
hash: true, //为静态资源生成hash值
chunks: ['vendors', 'index'], //需要引入的chunk, 不配置就会引入所有页面的资源
minify: { //压缩HTML文件
removeComments: true, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
});
new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
favicon: './src/img/favicon.ico', //favicon路径, 通过webpack引入同时可以生成hash值
filename: './view/list.html', //生成的html存放路径, 相对于path
template: './src/view/list.html', //html模板路径
inject: true, //js插入的位置, true/'head'/'body'/false
hash: true, //为静态资源生成hash值
chunks: ['vendors', 'list'], //需要引入的chunk, 不配置就会引入所有页面的资源
minify: { //压缩HTML文件
removeComments: true, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
});
其它插件
new webpack.HotModuleReplacementPlugin() // 热加载
HotModuleReplacementPlugin() // 代码热替换
NoErrorsPlugin() // 报错但不退出webpack进程
OpenBrowserPlugin() // 自动打开浏览器
webpack使用
分析多个模块的公用代码提取并单独打包
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
module.exports = {
entry: {
page1: './main1.js',
page2: './main2.js'
},
output: {
path: 'build',
filename: '[name].js'
},
plugins: [
commonsPlugin
]
}
文件引用忽略扩展名配置
如果你希望在require文件时省略文件的扩展名, 只需要在webpack.config.js中添加 resolve.extensions
来配置。
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
// 现在你require文件的时候可以直接使用require('file'), 不用使用require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
css样式和图片的加载
首先你需要用require()
去加载你的静态资源(named as they would with node's require()
):
require('./bootstrap.css');
require('./myapp.less');
var img = document.createElement('img');
img.src = require('./glyph.png');
当你require了CSS(less或者其他)文件, webpack会在页面中插入一个内联的<style>
, 去引入样式。当require图片的时候, bundle文件会包含图片的url, 并通过require()
返回图片的url。
但是这需要你在webpack.config.js
做相应的配置(这里还是使用loaders)
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
path: './build', // 图片和js会放在这
publicPath: 'http://mycdn.com/', // 这里用来生成图片的地址
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
}, // 用!去链式调用loader
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
// 内联的base64的图片地址, 图片要小于8k, 直接的url的地址则不解析
}
]
}
};
功能标识(Feature flags)
项目中有些代码我们只为在开发环境(例如日志)或者是内部测试环境(例如那些没有发布的新功能)中使用, 那就需要引入下面这些魔法全局变量(magic globals):
if (__DEV__) {
console.warn('Extra logging');
}
// ...
if (__PRERELEASE__) {
showSecretFeature();
}
同时还要在webpack.config.js中配置这些变量, 使得webpack能够识别他们。
// webpack.config.js
// definePlugin 会把定义的string 变量插入到Js代码中。
var definePlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
__PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false'))
});
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [definePlugin]
};
配置完成后, 就可以使用 BUILD_DEV=1 BUILD_PRERELEASE=1 webpack
来打包代码了。
值得注意的是, webpack -p
会删除所有无作用代码, 也就是说那些包裹在这些全局变量下的代码块都会被删除, 这样就能保证这些代码不会因发布上线而泄露。
多个入口文件
如果你有两个页面:profile和feed。如果你希望用户访问profile页面时不加载feed页面的代码, 那就需要生成多个bundles文件:为每个页面创建自己的“main module”(入口文件)。
// webpack.config.js
module.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js' // name是基于上边entry中定义的key
}
};
在profile页面中插入<script src="build/Profile.js"></script>
。feed也一样。
优化通用代码
Feed和Profile页面存在大量通用代码(比如React、公共的样式和组件等等)。webpack可以抽离页面间公共的代码, 生成一个公共的bundle文件, 供这两个页面缓存使用:
// webpack.config.js
var webpack = require('webpack');
var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('common.js'); // 引入插件
module.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js' // 为上面entry的key值
},
plugins: [commonsPlugin]
};
在上一步引入自己的bundle之前引入<script src="build/common.js"></script>
异步加载
虽然CommonJS是同步加载的, 但是webpack也提供了异步加载的方式。这对于单页应用中使用的客户端路由非常有用。当真正路由到了某个页面的时候, 它的代码才会被加载下来。
指定你要异步加载的 拆分点。看下面的例子
if (window.location.pathname === '/feed') {
showLoadingState();
require.ensure([], function() { // 这个语法痕奇怪, 但是还是可以起作用的
hideLoadingState();
require('./feed').show(); // 当这个函数被调用的时候, 此模块是一定已经被同步加载下来了
});
} else if (window.location.pathname === '/profile') {
showLoadingState();
require.ensure([], function() {
hideLoadingState();
require('./profile').show();
});
}
剩下的事就可以交给webpack, 它会为你生成并加载这些额外的 chunk 文件。
webpack 默认会从项目的根目录下引入这些chunk文件。你也可以通过 output.publicPath
来配置chunk文件的引入路径
// webpack.config.js
output: {
path: "/home/proj/public/assets", // webpack的build路径
publicPath: "/assets/" // 你require的路径
}
相关推荐
webpack学习笔记(以防丢失).md
对webpack学习过程中的一些记录目前只包括webpack的基本配置相关的一些东西后期会更新webpack中的一些编译原理及一些插件的实现
Webpack 是一个流行的模块...通过《Webpack学习笔记》这样的教程,你可以逐步掌握Webpack的基础和进阶用法,将其有效地应用于项目中,实现高效、模块化的前端开发。在学习过程中,不断实践和查阅官方文档是至关重要的。
此笔记包含了前端代码规范、前端工具使用笔记、Ajax、Axios学习笔记、...Webpack学习笔记、前端JS工具库使用笔记、前端UI库使用记录笔记、前端安全学习笔记、前端部署相关笔记、微信小程序学习笔记、正则表达式学习...
Webpack五个核心概念一,参赛入口(Entry)指示Webpack以哪个文件为入口起点开始打包,分析内置内部依赖图。二,输出输出(输出)指示Webpack打包后的资源包输出到那里去,以及如何命名。三,装载机加载程序让...
Webpack学习笔记 Vue笔记整合 UmiJS笔记 TypeScrip笔记 Scss笔记 React笔记 ReactHooks笔记 Promise学习笔记 Mobx学习笔记 HTML+CSS+JS基础笔记 Git学习笔记 ES6及后续版本 Chrome开发使用笔记 Ajax、Axios学习笔记 ...
除了的webpack基本配置,还可以进一步添加配置,优化合并文件,加快编译速度。下面是生产环境配置文件webpack.production.js,与wenbpack.config.js相比其不需要一些dev-tools,dev-server和jshint校验等,将与开发...
Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。在构建大型应用时,随着代码量的增加,一次性加载所有代码可能导致页面加载速度变慢,用户体验下降。为了解决这个问题,Webpack 提供了代码分割(Code ...
Webpack使用教程(基础) [TOC] 在开始之前,我们先来看以下Webpack官网首页给我们提供的图片,并思考一下该图片用意 一.Webpack基本介绍 1.1 概念的引入 思考:在网页中,我们经常会引入哪些常见的静态资源 JS .js ...
适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究...
记录自己学习webpack与Vue的过程
课程中,开发者将深入学习Vue3的响应式原理、Composition API的使用、React组件设计模式、Hooks的最佳实践,以及Webpack的配置与优化技巧。这些知识点不仅涵盖了基础理论,还包括实战经验,帮助学员在面试中脱颖而出...
最后,“下午知识点webpack”可能是一份具体的笔记或教学材料,涵盖了某个特定主题,如Webpack 4的新特性、性能优化策略,或者是解决某些特定问题的方法。 总的来说,Webpack 是一个功能强大的工具,它可以帮助...
笔记-webpack5学习指南-V1.0
"前端 学习笔记.zip"这个压缩包文件包含了关于前端开发的学习资料,特别是对于Web应用程序的开发有着深入的探讨。标签"web app"暗示了这些笔记主要关注的是构建Web应用程序的相关技术。 在压缩包中的"MyBatis-Plus...