本文章之前有写过关于 webpack 中如何使用 hash 和 devserver 的例子,有需要的可以去查看一下:
如何使用 Hash: http://blog.csdn.net/hsl0530hsl/article/details/78474026
如何使用 Server: http://blog.csdn.net/hsl0530hsl/article/details/78419693
本文主要记录一下,webpack 的一个完整实例,以及一些相关的优化。
首先贴一个整体的结构图:
每个文件的具体内容,如下作展示:
1、package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "This is just a test",
"main": "dist/bundle.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack",
"server": "webpack-dev-server --open"
},
"keywords": [
"webpack",
"dev-server"
],
"author": "slHuang",
"license": "ISC",
"devDependencies": {
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.4",
"style-loader": "^0.19.0",
"css-loader": "^0.28.7",
"postcss-loader": "^2.0.8",
"autoprefixer": "^7.1.6",
"babel-core": "^6.26.0",
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-react": "^6.24.1",
"babel-preset-env": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"babel-plugin-transform-runtime": "^6.23.0",
"extract-text-webpack-plugin": "^3.0.2"
},
"dependencies": {
"babel-runtime": "^6.26.0"
}
}
postcss-loader 与 autoprefixer 一起使用可以给 css 自动添加前缀。
style-loader 将 JS 字符串生成为 style 节点。
css-loader 将 CSS 转化成 CommonJS 模块,注意使用 options 添加 module 配置。
html-webpack-plugin 根据模板html生成引入js后的html
babel-core 和 babel-preset-env 用来处理 js 的转换和压缩
babel-preset-react 编译JSX
使用 npm install 将需要的插件安装好。具体如何安装以及开发环境的介绍,可以查看本人的其他文章。
2、index.temp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test webpack</title>
</head>
<body>
<h4>This is just a test of the webpack!</h4>
</body>
</html>
这里只需要写一个单纯的 html 模板就可以了,不用引进 css 或是 js 相关的文件,后面 webpack 会自动引进这些文件的。另外页面的一些其他内容(页面元素)可以通过 js 动态生成。
3、webpack.config.js
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");//根据模板html生成引入js后的html
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
devtool: "eval-source-map",
entry: "./js/requireAddDiv.js",
output: {
path: __dirname + "/dist",
filename: "bundle.[hash].js"
},
devServer: {
contentBase: "./",
historyApiFallback: true,
inline: true
},
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader?cacheDirectory=true",
options: {
presets: ["env", "react"],
plugins: ["transform-runtime"]
}
},
exclude: /node_modules/
},
/*{//这种方式只是解析 css,并不会分离 css
test: /\.css$/,
use: [
"style-loader",// 将 JS 字符串生成为 style 节点
{
loader: "css-loader",// 将 CSS 转化成 CommonJS 模块
options: {
module: true
}
},
{
loader: "postcss-loader",//可以自动添加前缀
options: {
plugins: function () {
return [
require("autoprefixer")
];
}
}
}
]
}*/
{//分离css需要使用这样的形式
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader",
{
loader: "postcss-loader",//可以自动添加前缀
options: {
plugins: function () {
return [
require("autoprefixer")
];
}
}
}
]
})
}
]
},
plugins: [
new webpack.BannerPlugin("版权所有,盗版必究!"),
new HtmlWebpackPlugin({
template: __dirname + "/index.temp.html"
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false, // remove all comments
},
compress: {
warnings: false
}
}),
new ExtractTextPlugin("css/styles-[hash].css")
]
};
处理 babel-loader 很慢的问题:
有以下几点可以优化这个处理速度:
1、确保转译尽可能少的文件。你可能使用 /.js$/ 来匹配,这样也许会去转译 node_modules 目录或者其他不需要的源代码。可以带上特定的路径去转换,使得正则表达式尽量少的匹配文件。比如:/\.js/*\.js$/
2、使用 exclude 排除 node_modules 下的 js 文件
3、使用 cacheDirectory 选项,将数据缓存在内存中,没有改变的文件将会从内存中读取
4、引入 babel-plugin-transform-runtime 插件作为一个独立模块,来避免重复引入。’transform-runtime’ 插件告诉 babel 要引用 runtime 来代替注入。(babel 在每个文件都插入了辅助代码,使代码体积过大!比如对一些公共方法使用了非常小的辅助代码_extend, 默认情况下会被添加到每一个需要它的文件中)注意: 你必须执行 npm install babel-plugin-transform-runtime –save-dev 来把它包含到你的项目中,也要使用 npm install babel-runtime –save 把 babel-runtime 安装为一个依赖。
优化插件:
OccurenceOrderPlugin :为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
ExtractTextPlugin:分离CSS和JS文件
UglifyJsPlugin:压缩JS代码;
4、variables.js
let val = {values: "This is my first div added!"};
export default val;
5、requireAddDiv.js
import val from "./variables";
require("../css/index.css");
const div = document.createElement("div");
div.innerHTML = val.values;
document.body.appendChild(div);
6、index.css
body {
background-color: green;
color: blue;
}
最终页面的效果图如下: