阅读目录css
1.webpack配置了解html
webpack的配置文件是一个nodejs的module,使用CommonJS风格来编写的,好比以下:node
module.exports = { entry: './index', output: { path: __dirname + '/dist', filename: 'bundle.js' } }
webpack的配置文件能够随便命名,默认为 webpack.config.js,所以在项目的根目录下,直接运行 webpack就能够进行打包,可是也能够对webpack命名为其余的名字,好比把它放入 build/webpack.dev.js ,代码目录结构以下:jquery
### 目录结构以下: demo # 工程名 | |--- dist # 打包后生成的目录文件 | |--- node_modules # 全部的依赖包 | |--- src # 项目的文件包 | | |--- pages # 存放全部页面的文件 | | | |--- page1 | | | | |--- index.html # 第一个页面的html文件 | | | | |--- index.styl # 第一个页面的css文件 | | | | |--- index.js # 第一个页面的js文件 | | | |--- page2 | | | | |--- index.html # 第二个页面的html文件 | | | | |--- index.styl # 第二个页面的css文件 | | | | |--- index.js # 第二个页面的js文件 | |--- build | | |--- webpack.base.js # webpack 基本配置文件 | | |--- webpack.dev.js # 开发文件 | | |--- webpack.build.js # 打包线上文件 | |--- .gitignore | |--- README.md | |--- package.json
所以咱们在package.json 配置文件以下:webpack
"scripts": { "dev": "node build/webpack.dev.js", "build": "node build/webpack.build.js" }
进入项目的根目录后,运行 npm run dev 便可进行打包。git
1.1) 入口文件配置 entry参数github
entry入口文件能够是字符串的单入口文件,也能够是数组的多入口文件,可是咱们最多见的是一个对象的方式来组织入口文件。所以object中的key在webpack里至关于入口的name,能够用来生成文件的路径,也可使用来为此入口惟一的标识。
好比以下:web
entry: { 'page1': path.resolve(__dirname, '../src/pages/page1'), 'page2': path.resolve(__dirname, '../src/pages/page2') }
假如页面上有多个入口的话,这样一个个写比较麻烦,所以能够写一个函数以下:正则表达式
/* 获取项目中多个入口文件 */ function getEntries(paths) { // node 中同步获取文件列表 var files = glob.sync(paths), entries = {}; files.forEach(function(filepath) { var toArray = filepath.split('/'); var filename = toArray[toArray.length - 2]; entries[filename] = filepath; }); return entries; } var entries = getEntries('./src/pages/*/index.js'); Object.keys(entries).forEach(function(name) { entry[name] = entries[name] });
1.2) 输出文件:out参数npm
output参数是告诉webpack以什么方式来生成/输出文件,output有几个经常使用的参数如:path, publicPath, filename, chunkFilename, 以下代码:
output: { path: path.resolve(__dirname, '../dist'), publicPath: '/assets/', // 供插件在生产模式下更新内嵌到css、html文件里的相对路径url值 filename: 'static/js/[name].js', chunkFilename: '[id].bundle.js', }
1.3) path参数
path参数表示生成文件的根目录,须要传入一个绝对路径,如:path.resolve(__dirname, '../dist'),会解析成 /项目的根目录下/dist文件, path参数和filename参数会共同组成入口文件的完整路径。
1.4) publicPath
该参数表示的是一个URL路径(指向生成文件的根目录),能够用于css/js/images/font文件等资源的路径,能够确保网页正确的加载到这些资源文件。
1.5) publicPath参数 和 path参数的区别:
path参数是针对本地文件系统的,可是publicPath则针对的是浏览器,它既能够是一个相对路径,好比 '../../dist', 也能够是一个绝对路径,好比:'http://www.xxx.com/', 那么何时使用相对路径呢?何时使用绝对路径呢?若是是引用本项目下的文件,最好使用相对路径,若是是引用跨项目的文件,须要使用绝对路径。
1.6) filename
filename属性表示的是如何命名生成的入口文件,能够有以下规则:
1. [name], 指代入口文件的name,也就是上面的entry中的key。
2. [hash] 指代本次编译的一个hash版本,可是请注意,只要在同一次编译过程当中生成的文件,这个[hash]值就是同样的,每一次编译,hash值都是同样,也就是说不存在缓存文件,只要一编译全部的hash
都会改变。
3. [chunkhash] 指代当前chunk的一个hash版本,也就是说,在每次编译过程当中,每个chunk的hash都是不同的,若是某个chunk没有发生变化,那么该chunk的hash也不会发生变化,也就是能够理解若是页面的文件没有发生改变,那么chunk的hash也不会发生改变,所以未改变的文件会在缓存中读取。
1.7) chunkFilename
chunkFilename 参数 与 filename参数相似,都是用来定义生成的命名方式的,只不过,chunkFilename参数指定的是除了入口文件外的chunk。
1.8) module参数中的 rules 配置(其实rules就至关于以前的loaders):
module: { rules: [ { test: /\.js$/, include: [ path.resolve(__dirname, 'src/pages/**/*.js') ], exclude: /(node_modules)/, // 排除node_modules 文件 use: { loader: 'babel-loader', options: { presets: ['es2015'], plugins: ['transform-runtime'] } } } ] }
下面对一些子参数进行说明:
test: test实际上是一个使用正则表达式匹配文件的一种方式,好比上面的是,匹配以 .js结尾的文件。
include: 用来表示本rules 配置是针对那些目录/文件,好比上面的代码配置是针对 src/pages/ 下的全部js文件的。
exclude: 是用来排除掉那些文件的,好比上面的是 /(node_modules)/ 的意思是 排除掉 node_modules下的js文件的。
use: 使用到的loader的配置
use 下的 loader: 使用加载器名称。
options: 该参数是为当前loader设置的参数,对于babel也能够单独放在 .babelrc文件中,也就是说该参数能够在项目的根目录不包含.babelrc文件,把.babelrc文件移到该配置项来便可。
2.webpack CommonsChunkPlugin公共代码剥离
与单页应用相比,多页应用存在多个入口(每一个页面即一个入口),每一个入口意味着一套完整的js代码(包括业务逻辑和加载第三方库、框架)。而后在每一个页面中分别加载该文件便可,
CommonsChunkPlugin: 该插件是一个可选用于创建一个独立文件(chunk), 这个文件包括多个入口的chunk的公共模块,经过将公共模块拆出来,最终合成的文件可以在最开始的时候加载一次,便存到缓存中,供后续使用,优势是:会带来速度的提高,由于浏览器会迅速将公共的代码从缓存中提取出来
,而不是每次访问一个新页面时候,再去加载一个更大的文件。
CommonsChunkPlugin 初始化有哪些参数?
name: 给这个包含公共代码的chunk命名。
filename: 命名打包后生成的js文件。
minChunks 公共代码的判断标准:某个js模块被多少个chunk(入口文件)加载了才算是公共代码。
chunks,表示须要在哪些chunk(配置中entry的每一项)里寻找公共代码进行打包,默认不设置,那么它的提取范围为全部的chunk。
下面是一个简单的CommonsChunkPlugin的实列含义:
var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin = ({ name: 'vender', // 这公共代码的chunk命名为 'vender' filename: '[name].bundle.js', // 生成的文件名为 vender.bundle.js minChunks: 2, // 设定要有2个chunk(即2个页面)加载的js模块才会被归入公共代码。 chunks: ['pageA', 'pageB'], // 只使用这些入口的 chunk }) var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin = ({ name: 'vender', // 这公共代码的chunk命名为 'vender' // filename: '[name].bundle.js', // 生成的文件名为 vender.bundle.js minChunks: Infinity, // 随着入口chunk愈来愈多,这个配置保证没其余的模块会打包进 公共的chunk })
下面是使用对 webpack CommonsChunkPlugin 详解的demo:
### 目录结构以下: demo # 工程名 | |--- dist # 打包后生成的目录文件 | |--- node_modules # 全部的依赖包 | |--- src # 项目的文件包 | | |--- common | | | |---css # 公用页面的css文件 | | | |---js # 公用页面的js文件 | | |--- libs | | | |--- jquery.js # 第三方库文件 | | |--- main.js # 入口文件 | |--- .gitignore | |--- README.md | |--- index.html # 首页文件 | |--- package.json | |--- webpack.config.js # 配置文件 | |--- webpack.production.config.js # 上线打包配置文件
1.1) 未使用 CommonsChunkPlugin 打包状况下
webpack.config.js 代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), publicPath: '/assets/', //指定资源文件引用的目录 filename: 'bundle.js' // 文件名为 bundle.js //filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 ] }
main.js代码以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./libs/jquery.js');
运行命令 npm run start 能够看到打包后的文件 bundle.js 代码内 包含第三方jquery框架的源码。
1.2)使用CommonsChunkPlugin
单一入口文件,分文件输出
webpack.config.js 代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'chunk', filename: 'chunk.js' // 把公用的 webpackJsonp 打包到chunk.js 里面去 }) ] }
main.js 代码以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test.js'); require('./common/js/test2.js'); require('./libs/jquery.js');
输出文件 chunk.js 和 main.js , chunk.js 是把公用的webpackJsonp打包到 chunk.js 代码里面去了。
可是 test.js 和 test2.js 及 jquery.js 被打包到 main.js 里面去了。
如今咱们能够将 test.js 和 test2.js 打包到chunk.js , 以下webpack配置代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', chunk: ['./src/common/js/test.js', './src/common/js/test2.js'] }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'chunk', filename: 'chunk.js' // 把公用的 webpackJsonp 打包到chunk.js 里面去 }) ] }
1.3) 单一入口,模块重复引用,最终把相同的模块打包到 入口文件内。
webpack.config.js 配置以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js' }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'chunk', minChunks: 2 }) ] }
main.js 代码以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2'); test.js代码以下: require('./test2'); var test1 = 11; exports.test1 = test1;
test2模块被引用了两次打包,可是最终模块被打包到main.js里面去了,minChunks: 2 的含义是 至少入口文件引用2个相同的模块会被打包到main.js 里面去。
1.4) 多入口,模块重复引用,将多个引用的模块被打包到公共模块。以下webpack.config.js代码:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'chunk', minChunks: 2 }) ] }
main.js代码以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2'); main2.js代码以下: var test1 = require('./common/js/test'); var test2 = require('./common/js/test2'); console.log(test1); console.log(test2);
如上代码: main.js 和 main2.js 都引用了 test.js 和 test2.js,打包后,test.js和 test2.js 被打包到 chunk.js内。 minChunks的含义是:至少引用了
2个相同的模块才会被打包到 chunk.js里面去。默认为2.
1.5)将第三方业务框架分开打包。
webpack.config.js 代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'] }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: ['chunk', 'jquery'], minChunks: 2 }) ] }
上面打包后 在页面上 会先加载 jquery.js,该模块包含了全部的模块文件,包括webpackJSon依赖代码,而后就是加载chunk.js,最后就是 main.js 和 main2.js了。
注意:webpack使用插件 CommonsChunkPlugin进行打包的时候,将符合引用次数的(minChunks)的模块打包到name参数的数组的第一个块内(chunk), 而后数组里面的依次打包,(查找entry里面的key), CommonsChunkPlugin中的最后一个块包含webpack生成的在浏览器上使用各个块的加载代码,
因此页面上使用的时候最后一个块必须先加载。
因此咱们在页面上会先看到先 加载 jquery.js ,查看该代码就会看到包含全部的代码,而后加载chunk.js代码,最后就是main.js和main2.js代码了。
1.6)minChunks: infinity
webpack.config.js代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'], }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'jquery', minChunks: 2 }) ] }
main.js 代码以下:
require('./common/css/style.css'); import './common/css/stylus.styl'; require('./common/js/test'); require('./common/js/test2');
main2.js代码以下:
var test1 = require('./common/js/test'); var test2 = require('./common/js/test2'); console.log(test1); console.log(test2);
运行代码后 发现main.js和 main2.js共同也能用的代码 test.js和 test2.js 代码被打包到jquery.js里面去了。
当把 上面的 webpack.config.js的代码 minChunks 修改成 minChunks: Infinity 后, test.js 和 test2.js代码都被打包到 main.js和main2.js代码内了。
1.7)参数chunks
webpack.config.js 代码以下:
// 导入路径包 const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { //开启sourceMap便于调试 devtool: 'eval-source-map', //入口文件, entry: { main: './src/main.js', main2: './src/main2.js', jquery: ['./src/libs/jquery.js'], }, output: { // 输出文件到当前目录下的 build文件夹内 path: path.resolve(__dirname, 'build'), filename: '[name].js' // 能够打包为多个文件 }, resolve: { extensions: ['*', '.js', '.json'], }, // 使用loader模块 module: { /* * 在webpack2.0版本已经将 module.loaders 改成 module.rules, 固然module.loaders也是支持的。 * 同时链式loader(用!链接)只适用于module.loader,同时-loader不可省略 */ rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 设置css模块化,详情参考 https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 参考 https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } }] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader'] }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ //须要排除的目录 } ] }, // 配置devServer各类参数 devServer: { // contentBase: "./", // 本地服务器所加载的页面所在的目录 hot: true, // 配置HMR以后能够选择开启 historyApiFallback: true, // 不跳转 inline: true // 实时刷新 }, plugins: [ new HtmlWebpackPlugin({ template: './index.html' // 模版文件 }), new webpack.HotModuleReplacementPlugin(), // 热加载插件 new CommonsChunkPlugin({ name: 'jquery', minChunks: 2, chunks: ['main', 'main2'] }) ] }
chunks 代码 包含['main', 'main2'],的含义是 都引用的模块才会打包到公用的模块 (jquery)内。
3.了解ProvidePlugin的用途
该插件的做用是 自动加载模块,典型的列子:好比自动加载jquery,首先须要使用 npm install --save jquery 后,在webpack.config.js 加以下配置:
config.plugins.push( new Webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }));
这样配置完成后,咱们在index.js 能够直接使用 $ 和 jQuery了,如:console.log(jQuery('body'));
3.2) 添加hash
每次打完包后,咱们看到 都会生成三个文件,分别是manifest.js, vendor.js. 和 页面上的业务js,manifest 是业务模块全部须要依赖的js,好比:webpackJsonp,而vendor.js 咱们这边打包成第三方框架或库,咱们这边是
jquery,每次打包后都会生成这三个文件,可是文件名都是同样的,浏览器可能缓存上一次的结果而没法加载最新的数据。所以咱们须要添加 hash。
为了解决上述问题,咱们须要为打包后的文件名添加hash值,这样每次修改后打包的hash文件值将会发生改变,浏览器会从服务器端下载最新的文件。
基本配置以下:
module.exports = { output: { path: path.resolve(__dirname, '../dist'), publicPath: '', filename: isLine ? 'static/js/[name].[chunkhash:5].js' : 'static/js/[name].js' } }
上面的代码 首先判断是不是在线上环境仍是平常环境,若是是在线上打包的话,添加 [chunkHash:5]变量,表示打包后的文件中加入5位的hash值。
3.3) 修改 vendor配置
上面解决浏览器缓存问题后,每次打包生成一个新的5位的hash编码值,可是问题又来了,当我修改某一个js文件的时候,vendor.js的hash值也跟着改变了,咱们明白 vendor是咱们打包第三方库jquery的,jquery我并无改动,
为了解决上面的问题,咱们须要使用 CommonsChunkPlugin 插件来配置;以下:
module.exports = { new Webpack.optimize.CommonsChunkPlugin({ name: ['vendor','manifest'], minChunks: 2 }) };
vendor.js 是打包库文件,而manifest.js 是打包模块中依赖的文件,当某个js文件发生改变的话,manifest是页面加载时启动文件,因此hash值会发生改变。而vendor代码被抽取出来后做为一个单独文件,源码没有改动的话,所以hash值就不会发生改变了。
webpack 多页应用架构系列实战git代码