这篇文章是在看阮一峰老师在GitHub上发表的webpack学习文档的时候,翻译出的文档说明webpack 阮一峰教程 ,纯手打非机翻。javascript
最后两个demo没有打上来,翻译好会补上来。文中有一小部分文字是我针对这个知识点的理解,就几行。css
若是有错误,欢迎指出。html
再次感谢阮一峰老师。前端
前端构建工具,与gulp和grunt 相似java
做为打包工具,与browserify 相似node
# be equivalent to
$ webpack main.js bundle.js
复制代码
配置文件是 webpack.config.js
react
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
复制代码
常见的命令们jquery
生产环境的应用须要在package.json中配置script :webpack
"dev": "webpack-dev-server --devtool eval --progress --colors",
"deploy": "NODE_ENV=production webpack -p"
},
复制代码
就是第一个进入的文件,使用入口文件进行打包或者构建 demo1中的bundle.jsgit
在demo1 的例子中, main.js是入口文件
复制代码
在index.html 中:
<body>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
复制代码
webpack 会按照webpack.config.js 去构建 bundle.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
复制代码
使用命令webpack-dev-server
启动服务器
对于多页面网站,适合使用多个入口文件
在main1.js 和main2.js 中
document.write('<h1>Hello World</h1>');
// main2.js
document.write('<h2>Hello Webpack</h2>');
复制代码
index.html 中
<html>
<body>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
复制代码
在webpack.config.js 中
module.exports = {
entry: {
bundle1: './main1.js',
bundle2: './main2.js'
},
output: {
filename: '[name].js'
}
};
复制代码
loader 是预处理器,让webpack处理非js文件,将全部的文件转换为webpack可以处理的有效模块
loader的两个目标
babel-loader 是一个将jsx、es6格式的文件转换为js文件的工具。
在main.jsx中:
const ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello, world!</h1>,
document.querySelector('#wrapper')
);
复制代码
在index.html 中
<body>
<div id="wrapper"></div>
<script src="bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
]
}
};
复制代码
在config.js中,module.loaders 用来分配loaders,上面的插件使用了babel-loader,babel-preset-es2015,babel-preset-react 进行编译,test用来检测识别
还能够这样写
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
复制代码
能够预处理css 文件使用css—loader
main.js
require('./app.css');
复制代码
app.css
body {
background-color: blue;
}
复制代码
index.html
<html>
<head>
<script type="text/javascript" src="bundle.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
复制代码
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.css$/, loader: 'style-loader!css-loader' },
]
}
};
复制代码
这里须要注意到是,必须使用两个加载器来转换,css-loader 是用来读取cssfile,style-loader是用来将style标签插入到html页面的,不一样的loader使用‘!’来链接
一样,图片资源也能够在js 文件中 main.js
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);
var img2 = document.createElement("img");
img2.src = require("./big.png");
document.body.appendChild(img2);
复制代码
index.html
<html>
<body>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
};
复制代码
url转换image文件,若是小于8192不用特殊,就能够转化成数据url,否则的化就是正常的url。‘?’是用来给loader传递参数的
转化以后的图片以下:
<img src="data:image/png;base64,iVBOR...uQmCC">---小图
<img src="4853ca667a2b8b8844eb2693ac1b2578.png"> ---大图
复制代码
使用css-loader?modules
能够知足css模块的需求
main.js
var React = require('react');
var ReactDOM = require('react-dom');
var style = require('./app.css');
ReactDOM.render(
<div>
<h1 className={style.h1}>Hello World</h1>
<h2 className="h2">Hello Webpack</h2>
</div>,
document.getElementById('example')
);
复制代码
app.css
.h1 {
color:red;
}
:global(.h2) {
color: blue;
}
复制代码
index.html
<html>
<body>
<h1 class="h1">Hello World</h1>
<h2 class="h2">Hello Webpack</h2>
<div id="example"></div>
<script src="./bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader?modules'
}
]
}
};
复制代码
若是是css模块是行成本身的做用域?能够使用:global来进行开关 在上面的例子中只有第二个h1是红色的,由于css被本地做用域化了,两个h2都是蓝的,由于是全局的
webpack有不少管道系统来扩展他的功能,uglify是用来压缩js代码的
main.js
var longVariableName = 'Hello';
longVariableName += ' World';
document.write('<h1>' + longVariableName + '</h1>');
复制代码
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new uglifyJsPlugin({
compress: {
warnings: false
}
})
]
};
复制代码
使用plugins 来使用uglify,在exports的上面定义uglify
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;以及使用plugins 来使用uglify
html-webpack-plugin
可以建立index.html.open-browser-webpack-plugin
能在webpack加载的时候打开一个浏览器标签页
main.js
document.write('<h1>Hello World</h1>')
复制代码
index.html不须要写了哈哈哈哈
webpack.config.js
var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new HtmlwebpackPlugin({
title: 'Webpack-demos',
filename: 'index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080'
})
]
};
复制代码
这个例子中能够看到咱们不须要写一个index.html 不须要咱们本身打开浏览器,webpack作好了
main.js
document.write('<h1>Hello World</h1>');
if (__DEV__) {
document.write(new Date());
}
复制代码
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
var webpack = require('webpack');
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [devFlagPlugin]
};
复制代码
若是咱们使用下面这行代码将环境变量设置为true,能够看到了日期
$ env DEBUG=true webpack-dev-server
复制代码
相对于大型的app来讲,全部的代码放到一个单独的文件会致使低效率的,webpack提供拆分红块的这种机制, 尤为是在某些条件小才会有需求的代码块,这些代码块应该在须要的时候加载,不须要的时候就不加载
使用require.ensure 来定义一个拆分点,用来告诉webpack 这个./a.js应该从bundle.js 中拆分,而且生成一个单独的文件
main.js
// main.js
require.ensure(['./a'], function(require) {
var content = require('./a');
document.open();
document.write('<h1>' + content + '</h1>');
document.close();
});
复制代码
a.js
module.exports = 'Hello World';
复制代码
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
复制代码
web.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
复制代码
在运行的时候,其实webpack构建了两个块,bundle.js 和 1.bundle.js(来自a.js),只有在须要的时候加载1.bundle.js
另外一种代码拆分的方式是使用bundle-loader
在main.js 文件中
// 如今咱们须要a.js了,将会绑定在另外一个文件中
// 下面这句是告诉webpack 从别的块中加载a.js
var load = require('bundle-loader!./a.js');
// 等待a.js可用的时候,咱们就能获取到这个exports
// 能够使用异步来等待
load(function(file) {
document.open();
document.write('<h1>' + file + '</h1>');
document.close();
});
复制代码
当多个script有公共的代码块时候, 咱们但愿把这个抽取出来行成一个独立的文件。咱们能够使用commonschunkplugin来实现这个功能
例以下面的main1.jsx和main2.jsx
// main1.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('a')
);
// main2.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h2>Hello Webpack</h2>,
document.getElementById('b')
);
复制代码
index.html
<html>
<body>
<div id="a"></div>
<div id="b"></div>
<script src="init.js"></script>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
复制代码
webpack.config.js
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
bundle1: './main1.jsx',
bundle2: './main2.jsx'
},
output: {
filename: '[name].js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
]
},
plugins: [
new CommonsChunkPlugin('init.js')
]
}
复制代码
使用Commonschunkplugin还能够实现吧script标签内的三方库抽取出造成一个单独的文件
例如jQuery
main.js
var $ = require('jquery');
$('h1').text('Hello World');
复制代码
index.html
<html>
<body>
<h1></h1>
<script src="vendor.js"></script>
<script src="bundle.js"></script>
</body>
</html>
复制代码
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './main.js',
vendor: ['jquery'],
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js')
]
};
复制代码
commonchunkplugin中有两个参数,第一个是抽取出的块的名字,第二个是抽取出以后的文件
若是想要让某个模块全局可用, 例如不使用require('jquery')却能够全局使用$和 jQuery, 能够使用ProvidePlugin来实现.
main.js
$('h1').text('Hello World');
复制代码
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './main.js'
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
]
};
复制代码
data.js
var data = 'Hello World';
复制代码
使用externals来暴露全局变量 // webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
]
},
externals: {
// require('data') is external and available
// on the global var data
'data': 'data'
}
};
复制代码
在externals属性中data做为全局变量在script中。
在main.jsx 中使用data:
var data = require('data');
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h1>{data}</h1>,
document.body
);
复制代码