webpack 多页面构建
目标:
- 基于webpack支持react多页面构建(不用gulp,gulp-webpack 构建速度太慢[3]), generator-react-webpack 对单页面支持很好,但对多页面,需要改造
- 提高开发人员的效率
- 并能对项目进行足够的性能优化
- 提高构建的效率
配置文件编写(webpack.config.js)
示例:
var path = require('path');
var glob = require('glob');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var node_dir = path.join(__dirname, './node_modules/');
var HtmlWebpackPlugin = require('html-webpack-plugin');
// 获取所有入口文件
var getEntry = function(globPath) {
    var entries = {
        vendor: ['jquery','react','react-dom','./src/app'] // 类库
    };
    glob.sync(globPath).forEach(function(entry) {
        var pathname = entry.split('/').splice(-2).join('/').split('.')[0];
        entries[pathname] = [entry];
    });
    console.log(entries);
    return entries;
};
// 判断是否是在当前生产环境
var isProduction = process.env.NODE_ENV === 'production';
var entries = getEntry('./src/view/*/*.jsx');
var chunks = Object.keys(entries);
module.exports = {
    entry: entries,
    output: {
        path: path.join(__dirname, './dist'),
        filename: isProduction ?'js/[name].[hash:8].js':'js/[name].js',
        publicPath: '/dist/',
        chunkFilename: 'chunk/[name].chunk.js'
    },
    module: {
        noParse:[
            /*path.join(node_dir,'./react/dist/react.min.js'),
            path.join(node_dir,'./jquery/dist/jquery.min.js'),
            path.join(node_dir,'./react-dom/dist/react-dom.min.js')*/
        ],
        loaders: [{
            test: /\.jsx?$/,
            loader: 'babel',
            query: {
                presets: ['es2015', 'react']
            },
            exclude: node_dir
        }, {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract('style', 'css')
        }, {
            test: /\.less$/,
            loader: ExtractTextPlugin.extract('style', 'css!less')
        }, {
            test: /\.(png|jpe?g|gif)$/,
            loader: 'url?limit=8192&name=img/[hash:8].[ext]'
        }, {
            //文件加载器,处理文件静态资源
            test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: 'file?limit=10000&name=fonts/[hash:8].[ext]'
        }]
    },
    resolve: {
        extensions: ['', '.js', '.jsx', '.json'],
        alias: {
            mod: node_dir
        }
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery', // 使jquery变成全局变量,不用在自己文件require('jquery')了
            jQuery: 'jquery',
            React: 'react',
            ReactDOM: 'react-dom'
        }),
        // 类库统一打包生成一个文件
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: isProduction ? 'js/vendor.[hash:8].js':'js/vendor.js',
            minChunks: 3 // 提取使用3次以上的模块,打包到vendor里
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin(isProduction ? 'css/[name].[hash:8].css':'css/[name].css')
    ],
    devtool: isProduction ? null : 'source-map'
};
// 生成HTML文件
chunks.forEach(function(pathname) {
    if (pathname == 'vendor') {
        return;
    }
    var conf = {
        title: 'My App',
        filename: isProduction? '../view/' + pathname + '.html' : pathname + '.html',
        template: './src/template.html',
        inject: 'body',
        minify: {
            removeComments: true,
            collapseWhitespace: false
        }
    };
    if (pathname in module.exports.entry) {
        conf.chunks = ['vendor', pathname];
        conf.hash = false;
    }
    module.exports.plugins.push(new HtmlWebpackPlugin(conf));
});
Webpack的配置主要包括以下几大项目:
- entry:js入口源文件 - 多入口配置 - 为了使用多入口文件,你可以给entry传入一个对象。对象的key代表入口点名字,value代表入口点。当使用多入口点的时候,需要重载output.filename,否责每个入口点都写入到同一个输出文件里面了。使用[name]来得到入口点名字。 
- 例子: - {
 entry: {
 a: "./a",
 b: "./b",
 //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出
 //该方法可以添加多个彼此不互相依赖的文件
 c: ["./c", "./d"]
 },
 output: {
 path: path.join(__dirname, "dist"),
 filename: "[name].entry.js" // a.enrty.js, b.enrty.js, c.entry.js
 }
 }
 
 
- output:生成文件 - output参数是个对象,定义了输出文件的位置及名字. 
- 例子: - output: {
 path: "dist/js/page",
 publicPath: "/output/",
 filename: "[name].bundle.js"
 } path: 打包文件存放的绝对路径
 publicPath: 网站运行时的访问路径
 filename:打包后的文件名
 
- module:模块加载器 - 在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等静态文件都是模块,不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。loaders之间是可以串联的,一个加载器的输出可以作为下一个加载器的输入,最终返回到JavaScript上。 
- 例子: - module: {
 //加载器配置
 loaders: [
 //.css 文件使用 style-loader 和 css-loader 来处理
 {
 test: /\.css$/,
 loader: 'style-loader!css-loader'
 },
 //.js 文件使用 jsx-loader 来编译处理
 {
 test: /\.js$/,
 loader: 'jsx-loader?harmony'
 },
 //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理
 {
 test: /\.scss$/,
 loader: 'style!css!sass?sourceMap'
 },
 //图片文件使用 url-loader 来处理,小于8kb的直接转为base64
 {
 test: /\.(png|jpg)$/,
 loader: 'url-loader?limit=8192'
 }
 ]
 }
- 多个loader可以用在同一个文件上并且被链式调用。链式调用时从右到左执行且loader之间用“!”来分割。 
- 模块加载器(loader)自身可以根据传入不同的参数进行配置。 
 
- resolve:文件路径的指向 - webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀: 
- 例子: - resolve: {
 //查找module的话从这里开始查找
 root: '/pomy/github/flux-example/src', //绝对路径
 //自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名
 extensions: ['', '.js', '.json', '.scss'],
 //模块别名定义,方便后续直接引用别名,无须多写长长的地址
 alias: {
 AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 即可
 ActionType : 'js/actions/ActionType.js',
 AppAction : 'js/actions/AppAction.js'
 }
 }
 
- plugins:插件,比loader更强大,能使用更多webpack的api - 插件一般都是用于输出bundle的node模块。例如,uglifyJSPlugin获取bundle.js然后压缩和混淆内容以减小文件体积。类似的extract-text-webpack-plugin内部使用css-loader和style-loader来收集所有的css到一个地方最终将结果提取结果到一个独立的”styles.css“文件,并且在html里边引用style.css文件。 
- 例子: - var ExtractTextPlugin = require("extract-text-webpack-plugin"); module: {
 loaders: [
 {
 test: /\.css$/,
 loader: ExtractTextPlugin.extract("style-loader", "css-loader")
 },
 {
 test: /\.less$/,
 loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
 }
 ]
 },
 plugins: [
 new ExtractTextPlugin("[name].css")
 ]
- code-splitting 插件CommonsChunkPlugin - 将多次引用的模块单独打包 - new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
 filename: isProduction ? 'js/vendor.[hash:8].js':'js/vendor.js',
 minChunks: 3 // 提取使用3次以上的模块,打包到vendor里
 })
 
- 多页面 html 生成插件 html-webpack-plugin - 例子: - var HtmlWebpackPlugin = require('html-webpack-plugin'); chunks.forEach(function(pathname) {
 if (pathname == 'vendor') {
 return;
 }
 var conf = {
 title: 'My App',
 filename: isProduction? '../view/' + pathname + '.html' : pathname + '.html',
 template: './src/template.html',
 inject: 'body',
 minify: {
 removeComments: true,
 collapseWhitespace: false
 }
 };
 if (pathname in module.exports.entry) {
 conf.chunks = ['vendor', pathname];
 conf.hash = false;
 }
 module.exports.plugins.push(new HtmlWebpackPlugin(conf));
 });
- src目录下有个template.html文件,无需引入任何css和js,webpack会自动帮我们打包引入, - <%= htmlWebpackPlugin.options.title %>读取配置好的页面标题- <!DOCTYPE html> 
 <html lang="en">
 <head>
 <meta charset="UTF-8" />
 <title> <%= htmlWebpackPlugin.options.title %> </title>
 </head>
 <body>
 <div id="app"></div>
 </body>
 </html>
- 最终通过打包,会生成对应入口的html文件, 
 比如src/view/index/index.js会生成view/index/index.html- <!DOCTYPE html> 
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title> My App </title>
 <link href="/dist/css/vendor.abf9657f.css" rel="stylesheet">
 <link href="/dist/css/index/index.abf9657f.css" rel="stylesheet">
 </head>
 <body>
 <div id="app"></div>
 <script type="text/javascript" src="/dist/js/vendor.abf9657f.js"></script>
 <script type="text/javascript" src="/dist/js/index/index.abf9657f.js"></script>
 </body>
 </html>
- 你会发现相关资源文件都自动引入了,十分便捷。 
 
 
webpack 常用命令
- webpack 最基本的启动webpack命令
- webpack -w 提供watch方法,实时进行打包更新
- webpack -p 对打包后的文件进行压缩
- webpack -d 提供SourceMaps,方便调试
- webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
- webpack --profile 输出性能数据,可以看到每一步的耗时
- webpack --display-modules 默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
webpack dev server
- 配置示例: - var webpack = require('webpack');
 var WebpackDevServer = require('webpack-dev-server');
 var config = require('./webpack.config.js'); for (var i in config.entry) {
 // 每个入口文件加入 client websocket 热加载脚本
 config.entry[i].unshift(
 "webpack-dev-server/client?http://127.0.0.1:3000/",
 "webpack/hot/only-dev-server"
 );
 }
 config.module.loaders.unshift({
 test: /\.jsx?$/,
 loader: 'react-hot',
 exclude: /node_modules/
 });
 config.plugins.push(new webpack.HotModuleReplacementPlugin());
 new WebpackDevServer(webpack(config), {
 publicPath: config.output.publicPath,
 hot: true,
 historyApiFallback: true,
 stats: { colors: true }
 }).listen(3000, '127.0.0.1', function (err, result) {
 if (err) {
 console.log(err);
 }
 console.log('server start');
 });
- 用处 - 开启服务器调试环境
- 解决以下两个问题:
- webpack --watch 打包速度慢
- 不能做到hot replace
 
 
- 配置 - Content Base - 如果不进行设定的话,服务器伺服默认是在当前目录下。 
- 命令行设置 - webpack-dev-server --content-base build/
- webpack 配置 - devServer: {
 contentBase: './src/',
 historyApiFallback: true,
 hot: true,
 port: defaultSettings.port,
 publicPath: '/assets/',
 noInfo: false
 }
 
- publicPath - webpack server 伺服的 bundle 是在内存中的,其相对路径由 publicPath 字段指定。
- 如果用以上的配置,bundle 可以通过地址 localhost:8080/assets/bundle.js 访问到。(注意:访问的不是output目录下的文件而是内存中的数据!)
 
 
- 自动更新和热替换 - 配置: - var config = require("./webpack.config.js");
 config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
 var compiler = webpack(config);
 var server = new webpackDevServer(compiler, {
 hot: true
 ...
 });
 server.listen(8080);- 关键配置: - config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");- 在每个入口文件注入 client websocket 热加载脚本。 
 
webpack 多页面构建的更多相关文章
- vue webpack多页面构建
		项目示例地址: https://github.com/ccyinghua/webpack-multipage 项目运行: 下载项目之后 # 下载依赖 npm install # 运行 npm run ... 
- webpack 多页面支持 & 公共组件单独打包
		webpack - 多页面/入口支持 & 公共组件单独打包 webpack系列目录 webpack 系列 一:模块系统的演进 webpack 系列 二:webpack 介绍&安装 we ... 
- 使用webpack+vue.js构建前端工程化
		参考文章:https://blog.csdn.net/qq_40208605/article/details/80661572 使用webpack+vue.js构建前端工程化本篇主要介绍三块知识点: ... 
- 使用Vue和djangoframwork完成登录页面构建 001
		使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ... 
- webpack多页面应用打包问题-新增页面打包JS影响旧有JS资源
		webpack多页面应用打包问题:如果在项目里新增页面,pages目录中插入一个页面文件,然后打包代码,在webpack3中,新增页面文件上方文件打包出来的JS文件内容全部会改变,点击查看比对,发现问 ... 
- 完美解决Webpack多页面热加载缓慢问题【转载】
		版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/localhost_1314/article ... 
- vue-cli + webpack 多页面实例应用
		关于vue.js vue.js是一套构建用户界面的 轻型的渐进式前端框架.它的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.使用vue可以给你的开发带来极致的编程体验. 关于vu ... 
- webpack 多页面|入口支持和公共组件单独打包--转载
		转载自:http://www.jb51.net/article/117490.htm 本篇主要介绍:如何自动构建入口文件,并生成对应的output:公共js库如何单独打包. 多入口文件,自动扫描入口. ... 
- webpack前端自动化构建工具
		博主不易,不求赞赏,希望把自己遇到的难点写出来,以及希望自己能有能力写出一篇不错的博文. 前端构建工具本人 bootstrap+jquery用gulp vue+element 用webpack 本人最 ... 
随机推荐
- 记一次maven打包编译文件一直不正确
			maven打包发现war包解压后的class文件总是跟原Java不一样 后来发现pom中这么写到 <plugins> <plugin> <artifactId>ma ... 
- 用 Python 制作关不掉的端午安康弹窗
			端午节又称端阳节.龙舟节.重午节.龙节.正阳节.天中节等,端午节源自天象崇拜,由上古时代祭龙演变而来,因传说战国时期的楚国诗人屈原在五月五日跳汨罗江自尽,后来人们亦将端午节作为纪念屈原的节日,在端午节 ... 
- C语言学习笔记之switch有无break差别
			今天复习到了switch语句,我们正常的写法中,是经常把switch和break搭配在一起的 当我们把break去掉呢 可以看到,我们选择2时,的确会到case 2里面执行语句,可是没有break还是 ... 
- [问题记录] webpack devServer HtmlWebpackPlugin 没有加载 js、css
			webpack devServer 没有加载 js.css HtmlWebpackPlugin runtimeChunks 注入问题. 描述 写了一个极其简单的多页面 demo 启动开发服务器,发现样 ... 
- 浅析Facebook LibraBFT与比原链Bystack BBFT共识
			如果说什么是区块链的灵魂,那一定是共识机制. 它是区块链的根基.无论公链或是联盟链,共识机制都从基础上限制了区块链的交易处理能力和扩展性. 2019年6月18日,Facebook 发布了自己 Libr ... 
- 测试面试题集锦(四)| Linux 与 Python 编程篇(附答案)
			本文为霍格沃兹测试学院学员学习笔记. 本系列文章总结归纳了一些软件测试工程师常见的面试题,主要来源于个人面试遇到的.网络搜集(完善).工作日常讨论等,分为以下十个部分,供大家参考.如有错误的地方,欢迎 ... 
- Memcached高可用组件之repcached
			在前边的tomcat session server msm的那篇博客我们用memcached做tomcat session服务器,默认官方memcached是不支持主从同步的,为了解决memcache ... 
- jQuery的事件与 动画
			什么是事件: 事件的本质是委托. Jquery的 方法: $().css(); $().click(); 等等. 鼠标的事件: 区别在于:mouseover与mouseout再进入或离开后会执行这两个 ... 
- hdfs学习(三)
			HDFS 的 API 操作 使用url方式访问数据(了解) @Test public void urlHdfs() throws IOException { //1.注册url URL.setURLS ... 
- 浅析XML和JSON的区别
			前言 今天做接口对接时,发现对方竟然是通过XML进行数据传输,当时冒出的第一个想法就是:WTF,这都什么年代了,还在用XML,是来搞笑的吧,JSON它不香吗? 想法归想法,但对接还是要完成的是吧?然后 ... 
