什么是 webpack?
webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。
任何静态资源都可以被webpack视作模块,然后模块之间也可以相互依赖,通过webpack对模块进行预处理后,可以打包成我们想要的静态资源。
webpack的官网是 http://webpack.github.io/
文档地址是 http://webpack.github.io/docs/
webpack支持哪些功能特性:
1、对 CommonJS 、 AMD 、ES6的语法做了兼容,意思也就是我们基本可以无痛迁移旧项目
2、串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持。比如:babel-loader,有效支持ES6,支持 React 热插拔(见 react-hot-loader )。能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
3、可以通过配置,打包成多个文件。有效利用浏览器的缓存功能提升性能。可以基于配置或者智能分析打包成多个文件,实现公共模块或者按需加载;
4、能被模块化的不仅仅是JS了,将样式文件和图片等静态资源也可视为模块进行打包。配合loader加载器,可以支持sass,less等CSS预处理器。支持对CSS,图片等资源进行打包,从而无需借助Grunt或Gulp
5、支持 SourceUrls 和 SourceMaps,易于调试,即使打包在一起依旧方便调试。
6、可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间。开发时在内存中完成打包,性能更快,完全可以支持开发过程的实时打包需求
7、具有强大的Plugin接口,大多是内部插件,使用起来比较灵活
8、webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
打包成多个资源文件
将项目中的模块打包成多个资源文件有两个目的:
将多个页面的公用模块独立打包,从而可以利用浏览器缓存机制来提高页面加载效率;
减少页面初次加载时间,只有当某功能被用到时,才去动态的加载。
安装webpack
npm install webpack -g
或者 npm install webpack --save-dev
一、 webpack命令行的几种基本命令(https://webpack.github.io/docs/cli.html)
$ webpack -h
$ webpack //最基本的启动webpack方法,执行一次编译 for building once for development
$ webpack -w 或 --watch //增量编译,监听变动并进行自动实时打包更新 for continuous incremental build in development (fast!)
$ webpack -p // 压缩混淆脚本,对打包后的文件进行压缩,for building once for production (minification)
$ webpack -d // 生成 SourceMaps映射文件,告知哪些模块被最终打包到哪里,方便调试。 to include source maps
$ webpack --display-error-details 查看查找过程,方便出错时能查阅更详尽的信息
$ webpack --config XXX.js 使用另一份配置文件来打包
webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
webpack --profile 输出性能数据,可以看到每一步的耗时
webpack --display-modules 默认情况下node_modules下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
--progress Display a compilation progress to stderr.
二、Webpack的模块加载器(http://webpack.github.io/docs/list-of-loaders.html)
Webpack对应Browsserify transform和RequireJS插件的工具称为loader。
Webpack把除了js之外的资源作为模块加载的时候,需要用到不同的加载器。
所有的加载器都需要通过npm来加载。
//对于html文件这里使用html-loader。它会将html文件加载成String形式
html-loader: npm install --save-dev html-loader
//react jsx代码热替换 React live code editing, https://github.com/gaearon/react-hot-loader
//Allows to live-edit React components while keeping them mounted and preserving their state
react-hot-loader:npm install react-hot-loader --save-dev
//Loads file as JSON
json-loader:
//Emits the file into the output folder and returns the (relative) url.
//有定义文件名的功能,"file?name=[path][name].[ext]?[hash]""
file-loader:
//The url loader works like the file loader, but can return a Data Url if the file is smaller than a limit.
url-loader:
//Loads coffee-script like JavaScript 将coffeescript加载为js
coffee-redux-loader:
//
coffee-loader:
//jsx-loader就可以添加?harmony参数使其支持ES6语法
jsx-loader: { test: /\.js$/, loader: 'jsx-loader?harmony' }
//Loads raw content of a file (as utf-8) 将一个文件加载为一段utf-8编码的string
raw-loader:
//Compiles Markdown to HTML
markdown-loader:
//Add exports of a module as style to DOM
style-loader
// Loads css file with resolved imports and returns css code
css-loader: npm install css-loader --save-dev
//Loads and compiles a less file
less-loader: npm install less-loader --save-dev
//Loads and compiles a scss file
sass-loader: npm install sass-loader node-sass --save-dev
//Turn ES6 code into vanilla ES5
babel-loader: npm install babel-loader babel-core babel-preset-es2015 --save-dev
//Add vendor prefixes to CSS rules using values from Can I Use
autoprefixer-loader:npm install autoprefixer-loader --save-dev
{ test: /\.less$/,
loader: 'style-loader!css-loader!autoprefixer-loader!less-loader' }
$ npm install style-loader css-loader url-loader babel-loader babel-core babel-preset-es2015 sass-loader file-loader html-loader react-hot-loader json-loader coffee-redux-loader raw-loader markdown-loader less-loader --save-dev
三、plugin插件 http://webpack.github.io/docs/list-of-plugins.html
(1) CommonsChunkPlugin
Webpack中将打包后的文件都称之为“Chunk”。这个插件可以将多个打包后的资源中的公共部分打包成单独的文件。智能提取公共部分来方便多页面之间进行复用。
用法
// 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' // Template based on keys in entry above
},
plugins: [commonsPlugin]
};
Add <script src="build/common.js"></script> //在html上去加载 common.js,且必须要最先加载
https://github.com/webpack/docs/wiki/optimization#multi-page-app
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
p1: "./page1",
p2: "./page2",
p3: "./page3",
ap1: "./admin/page1",
ap2: "./admin/page2"
},
output: {
filename: "[name].js"
},
plugins: [
new CommonsChunkPlugin("admin-commons.js", ["ap1", "ap2"]),
new CommonsChunkPlugin("commons.js", ["p1", "p2", "admin-commons.js"])
]
};
// <script>s required:
// page1.html: commons.js, p1.js
// page2.html: commons.js, p2.js
// page3.html: p3.js
// admin-page1.html: commons.js, admin-commons.js, ap1.js
// admin-page2.html: commons.js, admin-commons.js, ap2.js
(2) extract-text-webpack-plugin(https://github.com/webpack/extract-text-webpack-plugin)
独立出css样式,单独打包CSS,通过<link>引入样式而不是放在<style>标签内
API
ExtractTextPlugin.extract([notExtractLoader], loader, [options])
noExtractLoader可选参数,未提取的css会被这个loader处理。
loader列表,将资源转换为导出的css module,必选
ExtractTextPlugin.extract会在这个loader列表前插入一个loader,并且最后会执行loader列表所返回的module
ExtractTextPlugin needs to be added in two spots: in the Loader, and as a Plugin
在使用ExtractTextPlugin定义分割的CSS文件时,当entry只有一个js时,无论在这个文件里require什么名字的CSS 文件,最后都会被打包编译成webpack.config中定义的独立CSS
npm install extract-text-webpack-plugin --save-dev
用法:
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
// ...省略各种代码
module: {
loaders: [
{test: /\.js$/, loader: "babel"},
{test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")},
{test: /\.(jpg|png|svg)$/, loader: "url?limit=8192"},
{test: /\.scss$/, loader: "style!css!sass"}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('common.js'),
new ExtractTextPlugin("[name].css")
]
}
也支持所有独立样式打包成一个css文件。增加多一个参数即可。
new ExtractTextPlugin("style.css", {allChunks: true})
var webpack = require("webpack");
var ExtractTextPlugin = require("../");
module.exports = {
entry: {
a: "./entry.js",
b: "./entry2.js"
},
output: {
filename: "[name].js?[hash]-[chunkhash]",
chunkFilename: "[name].js?[hash]-[chunkhash]",
path: __dirname + "/assets",
publicPath: "/assets/"
},
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract(
"style-loader",
"css-loader?sourceMap",
{
publicPath: "../"
}
)},
{ test: /\.png$/, loader: "file-loader" }
]
},
devtool: "source-map",
plugins: [
new ExtractTextPlugin("css/[name].css?[hash]-[chunkhash]-[contenthash]-[name]", {
disable: false,
allChunks: true
}),
new webpack.optimize.CommonsChunkPlugin("c", "c.js")
]
};
(3)webpack-dev-server(http://webpack.github.io/docs/webpack-dev-server.html)
Webpack还提供了一个基于Node.js Express框架的开发服务器,它是一个静态资源Web服务器,对于简单静态页面或者仅依赖于独立服务的前端页面,都可以直接使用这个开发服务器进行开发。在开发过程中,开发服务器会监听每一个文件的变化,进行实时打包,并且可以推送通知前端页面代码发生了变化,从而可以实现页面的自动刷新。通过localhost:8080/webpack-dev-server/访问到页面了。默认情况下服务器以当前目录作为服务器目录。
npm install -g webpack-dev-server
npm install --save-dev webpack-dev-server
webpack-dev-server 默认使用webpack.config.js
webpack-dev-server --config xxx.js --hot --inline --quiet --progress --colors --port 2992
--inline use inline mode, automatically add webpack/hot/dev-server entry point to your configuration.
--hot to enable Hot Module Replacement,automatically add the HotModuleReplacementPlugin to the webpack configuration
用法:
entry: {
main: ['webpack/hot/dev-server', './main'],
vendor: ['lodash', './styles']
}
entry: [
'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./scripts/index' // Your appʼs entry point
]
热替换(Hot-replace)
调试React的话, 不用刷新页面
npm install --save-dev react-hot-loader
var webpack = require('webpack');
module: {
loaders: [
{ test: /\.jsx?$/, loaders: ['react-hot', 'jsx?harmony'], include: path.join(__dirname, 'src') }
]
}
plugins: [
new webpack.HotModuleReplacementPlugin() //或 使用webpack Dev Server的--hot选项
]
//
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}]
}
};
(4)optimize插件
Limit the maximum chunk count with --optimize-max-chunks 15
new webpack.optimize.LimitChunkCountPlugin({maxChunks: 15})
Limit the minimum chunk size with --optimize-min-chunk-size 10000
new webpack.optimize.MinChunkSizePlugin({minChunkSize: 10000})
new webpack.optimize.MinChunkSizePlugin({minChunkSize: 51200}) //~50kb
防止报错插件
new webpack.NoErrorsPlugin()
压缩JavaScript插件
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
去重复(相似)代码插件
new webpack.optimize.DedupePlugin()
预取模块插件
new webpack.PrefetchPlugin([context], request)
new webpack.PrefetchPlugin("react")
定义变量插件,可用于环境相关的编译
new webpack.DefinePlugin({
VERSION: JSON.stringify("5fa3b9"),
BROWSER_SUPPORTS_HTML5: true,
"typeof window": JSON.stringify("object")
})
//压缩React
new webpack.DefinePlugin({
"process.env": {
// This has effect on the react lib size
NODE_ENV: JSON.stringify("production")
}
})
//自动导出模块为自由变量
new webpack.ProvidePlugin({
$: "jquery" //$ is automatically set to the exports of module "jquery"
})
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
npm install jquery --save
var path = require("path");
var webpack = require("webpack");
module.exports = {
cache: true,
entry: {
jquery: "./app/jquery",
bootstrap: ["!bootstrap-webpack!./app/bootstrap/bootstrap.config.js", "./app/bootstrap"],
react: "./app/react"
},
output: {
path: path.join(__dirname, "dist"),
publicPath: "dist/",
filename: "[name].js",
chunkFilename: "[chunkhash].js"
},
module: {
loaders: [
// required to write "require('./style.css')"
{ test: /\.css$/, loader: "style-loader!css-loader" },
// required for bootstrap icons
{ test: /\.woff$/, loader: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff" },
{ test: /\.ttf$/, loader: "file-loader?prefix=font/" },
{ test: /\.eot$/, loader: "file-loader?prefix=font/" },
{ test: /\.svg$/, loader: "file-loader?prefix=font/" },
// required for react jsx
{ test: /\.js$/, loader: "jsx-loader" },
{ test: /\.jsx$/, loader: "jsx-loader?insertPragma=React.DOM" },
]
},
resolve: {
alias: {
// Bind version of jquery
jquery: "jquery-2.0.3",
// Bind version of jquery-ui
"jquery-ui": "jquery-ui-1.10.3",
// jquery-ui doesn't contain a index file
// bind module to the complete module
"jquery-ui-1.10.3$": "jquery-ui-1.10.3/ui/jquery-ui.js",
}
},
plugins: [
new webpack.ProvidePlugin({
// Automtically detect jQuery and $ as free var in modules
// and inject the jquery library
// This is required by many jquery plugins
jQuery: "jquery",
$: "jquery"
})
]
};
(5)通过gulp插件gulp-webpack来处理webpack任务
npm install --save-dev gulp-webpack
//gulpfile.js
var gulp = require('gulp');
var webpack = require('gulp-webpack');
var webpackConfig = require('./webpack.config');
gulp.task("webpack", function() {
return gulp
.src('./')
.pipe(webpack(webpackConfig))
.pipe(gulp.dest('./build'));
});
npm install gulp gulp-jshint gulp-rename gulp-uglify gulp-webpack --save-dev
//使用了gulp来进行代码压缩
var gulp = require('gulp'),
jshint = require('gulp-jshint'),
webpack = require('gulp-webpack'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename');
gulp.task('lint', function () {
gulp.src('./js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('webpack', function () {
gulp.src('./test.js')
.pipe(webpack())
.pipe(gulp.dest('dist/'))
.pipe(rename('all.min.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist'));
});
gulp.task('default', function(){
gulp.run('lint', 'webpack');
});
特殊模块的 Shim
https://github.com/webpack/docs/wiki/shimming-modules
长期缓存(http://webpack.github.io/docs/long-term-caching.html)
stats-webpack-plugin(https://github.com/unindented/stats-webpack-plugin)
四、Webpack的配置文件 (http://webpack.github.io/docs/configuration.html)
webpack默认使用webpack.config.js配置文件
.
多个loader之间用"!"串联起来,"-loader"是可以省略不写
context 绝对路径,用于解析entry选项的基础目录。缺省时为命令执行时所在目录
entry 入口文件配置,js文件引用的入口,一般每个entry 的属性对应一个文件
output 对应输出项配置,即入口文件最终要生成什么名字的文件、存放到哪里.
resolve
resolve.root 绝对路径,从这里开始查找我们开发的模块。
resolve.alias 模块别名定义,方便后续直接引用别名,无须多写长地址
例如:
alias: {
AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 即可
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
}
resolve.extensions 用于指明程序自动补全识别哪些后缀,意味着我们require模块可以省略不写后缀名
例如:extensions: ['', '.js', '.json', '.scss'] //注意一下, extensions 第一个是空字符串,对应不需要后缀的情况.
resolve.packageMains 检查package.json里的字段.
Default: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"]
resolve.modulesDirectories 设置依赖模块的目录名(不能是路径),查找模块时先从当前路径开始,逐层向上遍历父目录。
Default: ["web_modules", "node_modules"]
例如: “./node_modules”, “../node_modules”, “../../node_modules”, etc
//不解析正则表达式匹配的目录,提升打包性能
module.noParse:[/jquery/]
//排除匹配的目录
exclude:/node_modules/
//包含匹配的目录
include: [path.resolve(__dirname, "app/src"),path.resolve(__dirname, "app/test")]
new webpack.optimize.OccurrenceOrderPlugin()
node
(1)require
require()还支持在资源path前面指定loader,即require(![loaders list]![source path])形式
require("!style!css!less!bootstrap/less/bootstrap.less");
// “bootstrap.less”这个资源会先被"less-loader"处理,
// 其结果又会被"css-loader"处理,接着是"style-loader"
// 可类比pipe操作
require()时指定的loader会覆盖配置文件里对应的loader配置项。
除了在配置文件中对打包文件进行配置,还可以在代码中进行定义:require.ensure,例如:
require.ensure(["module-a", "module-b"], function(require) {
var a = require("module-a");
// ...
});
Webpack在编译时会扫描到这样的代码,并对依赖模块进行自动打包,运行过程中执行到这段代码时会自动找到打包后的文件进行按需加载。
五、react-bootstrap和react-redux
npm install --save react react-bootstrap
npm install --save react-redux
npm install --save-dev redux-devtools
六、Starter template for React with webpack.
https://github.com/webpack/react-starter
https://github.com/webpack/webpack-dev-middleware
webpack-dev-middleware是用来做服务端开发的时候,监听客户端用到的文件,在内存中生成修改后重新打包的文件,不用真正写到硬盘上。仅用于开发模式
http://webpack.github.io/docs/webpack-dev-server.html
webpack-dev-server是一个小型的node.js Express服务器,它使用webpack-dev-middleware中间件来为通过webpack打包生成的资源文件提供Web服务。它还有一个通过Socket.IO连接到webpack-dev-server服务器的小型运行时程序。webpack-dev-server发送关于编译状态的消息到客户端,客户端根据消息作出响应。
简单来说,webpack-dev-server就是一个小型的静态文件服务器。
当资源文件修改时,webpack-dev-server将通过socket.io通知客户端更新
一、自动刷新
webpack-dev-server有两种模式支持自动刷新
(1)iframe模式
在iframe模式下,页面是嵌套在一个iframe下的,在代码发生改动的时候,这个iframe会重新加载
使用iframe模式无需额外的配置,只需在浏览器输入
http://<host>:<port>/webpack-dev-server/<path>
示例
http://localhost:8080/webpack-dev-server/index.html
(2)inline模式
在inline模式下一个小型的webpack-dev-server客户端会作为入口文件打包,
这个客户端会在后端代码改变的时候刷新页面。
这两种模式都支持模块热替换,可使打包文件的局部刷新替换整个页面的重载刷新。
二、Hot Module Replacement(模块热替换)
在前端代码变动的时候无需整个刷新页面,只把变化的部分替换掉。
使用HMR功能也有两种方式:命令行方式和Node.js API。
(1)命令行方式同样比较简单,只需加入--line --hot选项。这时访问浏览器,你会看见控制台的log信息:
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
HMR前缀的信息由webpack/hot/dev-server模块产生,WDS前缀的信息由webpack-dev-server客户端产生。
(2)Node.js API方式需要做三个配置:
1)把webpack/hot/dev-server加入到webpack配置文件的entry项;
2)把new webpack.HotModuleReplacementPlugin()加入到webpack配置文件的plugins项;
3)把hot:true加入到webpack-dev-server的配置项里面。
A module can only be updated if you "accept" it. So you need to module.hot.accept the module in the parents or the parents of the parents... I. e. a Router is a good place or a subview.
具体的代码是:if(module.hot) module.hot.accept();
也可以使用一些插件去完成这个工作,例如webpack-module-hot-accept插件。不过,webpack-dev-server HMR结合react-hot-loader使用的时候,react-hot-loader会去做这个工作。
三、后端服务器与webpack-dev-server结合使用
webpack-dev-server只用来为webpack打包生成的资源文件提供服务,比如js文件、图片文件、css文件等;后端服务器除提供API接口外,还提供入口HTML。
要将webpack-dev-server与后端服务器结合使用,需要做三件事情。
第一、首页HTML文件是从后端服务器发出的,这时页面的根地址变成了后端服务器地址,怎么使得webpack产生的资源文件在请求资源的时候是向web-dev-server请求而不是后端服务器请求?只需在webpack配置文件中的output.publicPath配置项写上绝对URL地址,例如output.publicPath = "http://localhost:9090/assets/"。这时,webpack打包产生的资源文件里面的url地址都会是绝对地址,而不是相对地址。
第二、后端服务器产生的入口HTML文件要向webpack-dev-server请求资源文件,这个简单,只需在HTML文件中加入资源文件的绝对地址,例如:<script src="http://localhost:8080/assets/bundle.js">
第三、要使webpack-dev-server和它的运行时程序连接起来。这个简单,只需要使用inline模式即可。
最后我在将HMR和react-hot-loader结合使用的时候遇到了热替换不起作用的问题,即改变前端代码之后页面不是热替换而是冲刷。我在这里找到了答案。
react-hot-loader/docs/troubleshooting.md
四、webpack-dev-server命令行和devServer配置
命令行的选项覆盖devServer中的配置。
选项
--content-base <file/directory/url/port>
资源根目录,默认使用当前目录
--config
使用webpack-dev-server命令行的时候,会自动查找名为webpack.config.js的配置文件。如果你的配置文件名称不是webpack.config.js,需要在命令行中指明配置文件
webpack-dev-server --config webpack.config.dev.js
--inline
(1)启用inline模式,而不使用frame
(2)会自动把webpack-dev-server客户端加到webpack的入口文件配置中。Node.js API方式时需要手动把
webpack-dev-server/client?http://<path>:<port>/加到配置文件的入口文件配置处,因为webpack-dev-server没有inline:true这个配置项。 如:webpack-dev-server/client?http://localhost:8080
(3)console里显示状态信息
(4)通过http://<host>:<port>/<path>访问. 如:http://localhost:8080/index.html
--history-api-fallback
提供对history API调用的支持,比如使用HTML5的history API
// output.publicPath: '/foo-app/'
historyApiFallback: {
index: '/foo-app/'
}
//想用另一台电脑做调试,需要增加参数为开发服务器的IP地址
--host <hostname/ip>: hostname or IP.
--port <number>: port.
--quiet
不输出任何信息到console上
--no-info
不显示info(仅warning和error)信息到console上
--colors
输出的信息带颜色
--no-colors
输出的信息不带颜色
--hot
(1)启用hot模式,把webpack/hot/dev-server加入到webpack的入口文件配置中
(2)自动加入HotModuleReplacementPlugin,不要在配置中再第二次加入该插件
--lazy
lazy模式,不实时监控,但会对每个请求重新编译,不能和hot模式一起用
--https
webpack-dev-server提供HTTPS
--cert, --cacert, --key
Paths the certificate files
--open
opens the url in default browser
devServer: {
// all options optional
/*webpack-dev-server options*/
contentBase: "/path/to/directory",
// or: contentBase: "http://localhost/",
hot: true,
historyApiFallback: true,
// Add proxy to allow working with a back end on a different server/port
// Use "*" to proxy all paths to the specified server.
// see https://github.com/webpack/webpack-dev-server/pull/127
proxy: {
"/api/*": "http://localhost:9090"
},
//是否启用gzip压缩
compress:true,
/*webpack-dev-middleware options*/
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
// watch options (only lazy: false)
watchOptions: {
aggregateTimeout: 300,
poll: true
},
publicPath: "/assets/",
// custom headers
headers: { "X-Custom-Header": "yes" },
stats: { colors: true }
}
通过package.json的main指定主模块
webpack --watch
启动监听模式。开启监听模式后,没有变化的模块会在编译后缓存到内存中,而不会每次都被重新编译
// 加载器
module: {
// 加载器
loaders: [
// 解析.vue文件
{ test: /\.vue$/, loader: 'vue' },
// 转化ES6的语法
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ },
// 编译css并自动添加css前缀
{ test: /\.css$/, loader: 'style!css!autoprefixer'},
//.scss 文件想要编译,scss就需要这些东西!来编译处理
//install css-loader style-loader sass-loader node-sass --save-dev
{ test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
// 图片转化,小于8K自动转化为base64的编码
{ test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=8192'},
//html模板编译?
{ test: /\.(html|tpl)$/, loader: 'html-loader' },
]
},
// 转化成es5的语法
babel: {
presets: ['es2015'],
plugins: ['transform-runtime']
},
// 开启source-map,webpack有多种source-map,在官网文档可以查到
devtool: 'eval-source-map'