1. package.json 项目清单文件
version //版本号
description //描述
main //主程序入口
script //脚本
dependencies //依赖
2. .babelrc(babel的根配置文件)
3. script脚本
3.1. entry入口
上面的-f是文件名为entry
dist是打包后生成的目录,也就是你运行npm run entry后生成的entry的压缩文件
在index.html里引入
<script type="text/javascript" src="/entry/dist/_index.js"></script>
然后在index.js里写
alert('i am index')
entry可以是:Object、Function、promise、String
3.1.1. entry为Object的情况如下:
//在webpack.config.js文件里
//对象前面的key就是你生成dist目录后对应的文件名
let base = {
index: './index.js',
index1: './index1.js'
}
module.exports = {
entry:base,
//这里指定了生成的目录前要加'_你上面对应的文件名.js',所以最后输出的dist下的文件是_index.js和_index1.js
output: {
filename: '_[name].js'
}
}
运行
npm run entry
页面弹出'i am index'的弹窗
3.1.2. entry为Function
let base = {
index: './index.js',
index1: './index1.js'
}
function fn(){
return base
}
module.exports = {
entry:fn,
output: {
filename: '_[name].js'
}
}
3.1.3. entry为promise
function fn(){
return new Promise((resolve,reject)=>{
resolve(base)
})
}
module.exports = {
entry:fn,
output: {
filename: '_[name].js'
}
}
3.1.4. entry为String
let base = './index.js'
module.exports = {
entry:base,
output: {
filename: '_[name].js'
}
}
这里要注意如果是字符串dist目录生成的文件名,就会以默认的main开头,所以最后生成的dist目录为_main.js
3.2. output
output: {
//导出目录
path: path.resolve(__dirname, 'uuudist'),
publicPath: "/output/uuudist/", // server-relative
//包规范格式
libraryTarget:'umd',
library: "MyLibrary",
//文件名
chunkFilename:'[chunkhash]_[name].js',
//hash位数
hashDigestLength:3,
//导出文件
//hash ==> webpack编译过程
// chunkhash => webpack对每个文件的hash
filename: '_[name][chunkhash].js'
}
path用于定义导出目录的名称
你上面的第二个参数字符串就是你打包生成的目录名,你写的uuudist那就会生成一个uuudist的目录
filename:生成的文件名的格式
其中[name]是拿到你entry里面的对象里的key,而[chunkhash]是webpack编译的时候会认为每一个文件都是一个chunk,他会有一个hash算法来标识每一个文件,然后通过hashDigestLength来定义hash取多少位,使用[chunkhash]主要是用来作为时间戳解决缓存问题,要注意每次文件内容的改变会引起hash值的改变,所以文件不会去重是增量的,比如:原来目录下只有一个index1生成的文件
当你改变index1.js里的内容的时候,会重新对你当前dist下的目录重新生成一遍不同hash的文件
//包规范,一般默认使用umd,提供各种兼容模式
libraryTarget:'umd',
//当你写umd的时候就相当于
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["MyLibrary"] = factory();
else
root["MyLibrary"] = factory();
library: "MyLibrary",
//就相当于变量var MyLibrary,
//直接通过MyLibrary就可以拿到你包的导出内容
hash包括 hash和chunkhash
hash是整个webpack编译过程,也就是说你所有的文件都会生成一个同样的hash值
比如:
filename: '[hash]_[name].js'
最后生成的目录里的文件如下:chunkhash就像前面说的是webpack对每一个文件都有一个自己的hash值
filename: '[chunkhash]_[name].js'
chunkFilename:异步加载的文件名字
publicPath:异步加载文件的路径(前缀)
在index.js里
//异步加载
//第一个参数是依赖,第二个是function,第三个是文件名
require.ensure([],(require)=>{
require('./index1.js')
},'dynamic')
//当你要使用异步加载文件的时候就需要使用'/output/uuudist/异步加载的文件名'
publicPath: "/output/uuudist/",
//这里的[chunkhash]对应一个hash值,[name]对应你上面异步加载的第三个参数文件名'dynamic'
chunkFilename:'[chunkhash]_[name].js',
通过定义publicPath,和chunkFilename会在output/uuudist目录下生成一个异步加载的文件3.3. split
实现文件模块化
可以通过require和import实现模块化引入,下面在index.js里引入split.js里的内容
//split.js
console.log('I am a split')
//index.js
console.log('I am index')
import './split.js'
//require('./split')
最后只要引入index.js就能同时打印出I am a split和I am index
3.4. module
module.exports = {
entry:base,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module:{
rules:[
// Conditions, Results and nested Rules.
{
test: /\.jsx?$/,
exclude: [
'node_modules'
],
// flags to apply these rules, even if they are overridden (advanced option)
//webpack1的语法
// loader: "babel-loader",
// rule.use是数组形式和rule.loaders是它的别名
use:[{
loader: "babel-loader",
}]
},
]
}
};
module是一个对象,对象里面是一个rules规则数组,数组里面又是一个对象,他每次都会对文件走一遍rules,先进行test正则匹配看一下这个文件的文件名满足不满足这个正则,满足的话就开始走use这个数组,使用loader,这个loader就是使用babel-loader来转码成浏览器兼容的js,当发现node_modules里面的js的时候就不会用loader去转码,因为node_modules里面的文件都有一个预处理entry==>loaders==>webpack===>output,所以你即使不通过loader来转码,webpack也会去转的
3.5. resolve
resolve.alias用来处理别名,更容易维护
当前目录结构下的index.js里引入test/test/test.js
那么你就要这么写
//index.js
require('./test/test/test.js')
这样如果多个文件里都要使用它的话,你写起来就会很复杂,这时候我们就可以通过resolve里的alias来实现,alias是一个对象,里面是你定义的别名和路径
module.exports = {
resolve:{
alias:{
//这里的路径只能是绝对路径
test:path.resolve(__dirname,'test/test/test.js')
}
},
//entry ==> rules ===> webpack ==> output
module:{
rules:[
{
test: /\.jsx?$/,
exclude: [
'node_modules'
],
use:[{
loader: "babel-loader",
}]
},
]
}
};
然后你再引入这个test.js只需引入你定义的别名就行
//index.js
require('test')
//就相当于require('./test/test/test.js')
3.6. devtool
通过dectool:'source-map'可以实现在源文件中debugger
比如你在开发的时候在你的源文件index.js里写了一个debugger
//index.js
import test from 'test';
debugger;
console.log(test());
如果你不在webpack里面写dectool:'source-map'的话,你打包运行后就会发现它是在你打包生成的文件里debugger了
而我们都是希望在我们编写的文件里测试,所以我们就需要加
module.exports = {
// https://webpack.js.org/configuration/devtool/#devtool
devtool:'source-map',
// https://webpack.js.org/configuration/target/#target
};
再次运行,你就会发现确实在我们的源文件中debugger了3.7. loaders 预处理
module:{
//entry => loaders ==> webpack ==> output
rules:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: {
loader:'babel-loader'
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use:{
loader:'css-loader',
options: {
sourceMap: true
}
}
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback:'style-loader',
use:['css-loader',{
loader:'less-loader',
options: {
sourceMap: true
}
}]
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback:'style-loader',
use:['css-loader',{
loader:'sass-loader',
options: {
sourceMap: true
}
}]
})
},
{
test: /\.(png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/,
use: {
loader:'file-loader',
options:{
name:'[name]_[sha512:hash:base64:7].[ext]'
}
}
},
{
test: /\.html/,
use:{
loader:"html-loader",
options:{
minimize: false,
attrs:false
}
}
}
]
}
options是对每一个loader进行个性化配置
3.8. plugins
对webpack编译的生命周期做一个hook
module.exports = {
plugins:[
new webpack.ProvidePlugin({
$: 'jquery'
}),
new WebpackNotifierPlugin({
title: 'Webpack 编译成功',
contentImage: path.resolve(process.cwd(), './img/avatar.jpeg'),
alwaysNotify: true
}),
new ExtractTextPlugin({
filename: "[name].css",
disable: false,
allChunks: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: Infinity
})
],
module:{
rules:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use:{
loader:'css-loader',
options: {
sourceMap: true
}
}
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback:'style-loader',
use:['css-loader',{
loader:'less-loader',
options: {
sourceMap: true
}
}]
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback:'style-loader',
use:['css-loader',{
loader:'sass-loader',
options: {
sourceMap: true
}
}]
})
},
{
test: /\.(png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/,
use: {
loader:'file-loader',
options:{
name:'[name]_[sha512:hash:base64:7].[ext]'
}
}
},
{
test: /\.html/,
use:{
loader:"html-loader",
options:{
minimize: false,
attrs:false
}
}
}
]
}
};