目标:

  • 基于webpack支持react多页面构建(不用gulp,gulp-webpack 构建速度太慢[3]), generator-react-webpack 对单页面支持很好,但对多页面,需要改造
  • 提高开发人员的效率
  • 并能对项目进行足够的性能优化
  • 提高构建的效率

配置文件编写(webpack.config.js)

示例:

  1. var path = require('path');
  2. var glob = require('glob');
  3. var webpack = require('webpack');
  4. var ExtractTextPlugin = require('extract-text-webpack-plugin');
  5. var node_dir = path.join(__dirname, './node_modules/');
  6. var HtmlWebpackPlugin = require('html-webpack-plugin');
  7.  
  8. // 获取所有入口文件
  9. var getEntry = function(globPath) {
  10. var entries = {
  11. vendor: ['jquery','react','react-dom','./src/app'] // 类库
  12. };
  13. glob.sync(globPath).forEach(function(entry) {
  14. var pathname = entry.split('/').splice(-2).join('/').split('.')[0];
  15. entries[pathname] = [entry];
  16. });
  17. console.log(entries);
  18. return entries;
  19. };
  20. // 判断是否是在当前生产环境
  21. var isProduction = process.env.NODE_ENV === 'production';
  22. var entries = getEntry('./src/view/*/*.jsx');
  23. var chunks = Object.keys(entries);
  24. module.exports = {
  25. entry: entries,
  26. output: {
  27. path: path.join(__dirname, './dist'),
  28. filename: isProduction ?'js/[name].[hash:8].js':'js/[name].js',
  29. publicPath: '/dist/',
  30. chunkFilename: 'chunk/[name].chunk.js'
  31. },
  32. module: {
  33. noParse:[
  34. /*path.join(node_dir,'./react/dist/react.min.js'),
  35. path.join(node_dir,'./jquery/dist/jquery.min.js'),
  36. path.join(node_dir,'./react-dom/dist/react-dom.min.js')*/
  37. ],
  38. loaders: [{
  39. test: /\.jsx?$/,
  40. loader: 'babel',
  41. query: {
  42. presets: ['es2015', 'react']
  43. },
  44. exclude: node_dir
  45. }, {
  46. test: /\.css$/,
  47. loader: ExtractTextPlugin.extract('style', 'css')
  48. }, {
  49. test: /\.less$/,
  50. loader: ExtractTextPlugin.extract('style', 'css!less')
  51. }, {
  52. test: /\.(png|jpe?g|gif)$/,
  53. loader: 'url?limit=8192&name=img/[hash:8].[ext]'
  54. }, {
  55. //文件加载器,处理文件静态资源
  56. test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
  57. loader: 'file?limit=10000&name=fonts/[hash:8].[ext]'
  58. }]
  59. },
  60. resolve: {
  61. extensions: ['', '.js', '.jsx', '.json'],
  62. alias: {
  63. mod: node_dir
  64. }
  65. },
  66. plugins: [
  67. new webpack.ProvidePlugin({
  68. $: 'jquery', // 使jquery变成全局变量,不用在自己文件require('jquery')了
  69. jQuery: 'jquery',
  70. React: 'react',
  71. ReactDOM: 'react-dom'
  72. }),
  73. // 类库统一打包生成一个文件
  74. new webpack.optimize.CommonsChunkPlugin({
  75. name: 'vendor',
  76. filename: isProduction ? 'js/vendor.[hash:8].js':'js/vendor.js',
  77. minChunks: 3 // 提取使用3次以上的模块,打包到vendor里
  78. }),
  79. new webpack.optimize.UglifyJsPlugin({
  80. compress: {
  81. warnings: false
  82. }
  83. }),
  84. new ExtractTextPlugin(isProduction ? 'css/[name].[hash:8].css':'css/[name].css')
  85. ],
  86. devtool: isProduction ? null : 'source-map'
  87. };
  88. // 生成HTML文件
  89. chunks.forEach(function(pathname) {
  90. if (pathname == 'vendor') {
  91. return;
  92. }
  93. var conf = {
  94. title: 'My App',
  95. filename: isProduction? '../view/' + pathname + '.html' : pathname + '.html',
  96. template: './src/template.html',
  97. inject: 'body',
  98. minify: {
  99. removeComments: true,
  100. collapseWhitespace: false
  101. }
  102. };
  103. if (pathname in module.exports.entry) {
  104. conf.chunks = ['vendor', pathname];
  105. conf.hash = false;
  106. }
  107. module.exports.plugins.push(new HtmlWebpackPlugin(conf));
  108. });

Webpack的配置主要包括以下几大项目:

  • entry:js入口源文件

    • 多入口配置

      • 为了使用多入口文件,你可以给entry传入一个对象。对象的key代表入口点名字,value代表入口点。当使用多入口点的时候,需要重载output.filename,否责每个入口点都写入到同一个输出文件里面了。使用[name]来得到入口点名字。

      • 例子:

        1. {
        2. entry: {
        3. a: "./a",
        4. b: "./b",
        5. //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出
        6. //该方法可以添加多个彼此不互相依赖的文件
        7. c: ["./c", "./d"]
        8. },
        9. output: {
        10. path: path.join(__dirname, "dist"),
        11. filename: "[name].entry.js" // a.enrty.js, b.enrty.js, c.entry.js
        12. }
        13. }
  • output:生成文件

    • output参数是个对象,定义了输出文件的位置及名字.

    • 例子:

      1. output: {
      2. path: "dist/js/page",
      3. publicPath: "/output/",
      4. filename: "[name].bundle.js"
      5. }
      6.  
      7. path: 打包文件存放的绝对路径
      8. publicPath: 网站运行时的访问路径
      9. filename:打包后的文件名
  • module:模块加载器

    • 在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等静态文件都是模块,不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。loaders之间是可以串联的,一个加载器的输出可以作为下一个加载器的输入,最终返回到JavaScript上。

    • 例子:

      1. module: {
      2. //加载器配置
      3. loaders: [
      4. //.css 文件使用 style-loader 和 css-loader 来处理
      5. {
      6. test: /\.css$/,
      7. loader: 'style-loader!css-loader'
      8. },
      9. //.js 文件使用 jsx-loader 来编译处理
      10. {
      11. test: /\.js$/,
      12. loader: 'jsx-loader?harmony'
      13. },
      14. //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理
      15. {
      16. test: /\.scss$/,
      17. loader: 'style!css!sass?sourceMap'
      18. },
      19. //图片文件使用 url-loader 来处理,小于8kb的直接转为base64
      20. {
      21. test: /\.(png|jpg)$/,
      22. loader: 'url-loader?limit=8192'
      23. }
      24. ]
      25. }
    • 多个loader可以用在同一个文件上并且被链式调用。链式调用时从右到左执行且loader之间用“!”来分割。

    • 模块加载器(loader)自身可以根据传入不同的参数进行配置。

  • resolve:文件路径的指向

    • webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:

    • 例子:

      1. resolve: {
      2. //查找module的话从这里开始查找
      3. root: '/pomy/github/flux-example/src', //绝对路径
      4. //自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名
      5. extensions: ['', '.js', '.json', '.scss'],
      6. //模块别名定义,方便后续直接引用别名,无须多写长长的地址
      7. alias: {
      8. AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 即可
      9. ActionType : 'js/actions/ActionType.js',
      10. AppAction : 'js/actions/AppAction.js'
      11. }
      12. }
  • plugins:插件,比loader更强大,能使用更多webpack的api

    • 插件一般都是用于输出bundle的node模块。例如,uglifyJSPlugin获取bundle.js然后压缩和混淆内容以减小文件体积。类似的extract-text-webpack-plugin内部使用css-loader和style-loader来收集所有的css到一个地方最终将结果提取结果到一个独立的”styles.css“文件,并且在html里边引用style.css文件。

    • 例子:

      1. var ExtractTextPlugin = require("extract-text-webpack-plugin");
      2.  
      3. module: {
      4. loaders: [
      5. {
      6. test: /\.css$/,
      7. loader: ExtractTextPlugin.extract("style-loader", "css-loader")
      8. },
      9. {
      10. test: /\.less$/,
      11. loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
      12. }
      13. ]
      14. },
      15. plugins: [
      16. new ExtractTextPlugin("[name].css")
      17. ]
    • code-splitting 插件CommonsChunkPlugin

      • 将多次引用的模块单独打包

        1. new webpack.optimize.CommonsChunkPlugin({
        2. name: 'vendor',
        3. filename: isProduction ? 'js/vendor.[hash:8].js':'js/vendor.js',
        4. minChunks: 3 // 提取使用3次以上的模块,打包到vendor里
        5. })
    • 多页面 html 生成插件 html-webpack-plugin

      • 例子:

        1. var HtmlWebpackPlugin = require('html-webpack-plugin');
        2.  
        3. chunks.forEach(function(pathname) {
        4. if (pathname == 'vendor') {
        5. return;
        6. }
        7. var conf = {
        8. title: 'My App',
        9. filename: isProduction? '../view/' + pathname + '.html' : pathname + '.html',
        10. template: './src/template.html',
        11. inject: 'body',
        12. minify: {
        13. removeComments: true,
        14. collapseWhitespace: false
        15. }
        16. };
        17. if (pathname in module.exports.entry) {
        18. conf.chunks = ['vendor', pathname];
        19. conf.hash = false;
        20. }
        21. module.exports.plugins.push(new HtmlWebpackPlugin(conf));
        22. });
      • src目录下有个template.html文件,无需引入任何css和js,webpack会自动帮我们打包引入,<%= htmlWebpackPlugin.options.title %>读取配置好的页面标题

        1. <!DOCTYPE html>
        2. <html lang="en">
        3. <head>
        4. <meta charset="UTF-8" />
        5. <title> <%= htmlWebpackPlugin.options.title %> </title>
        6. </head>
        7. <body>
        8. <div id="app"></div>
        9. </body>
        10. </html>
      • 最终通过打包,会生成对应入口的html文件,
        比如src/view/index/index.js会生成view/index/index.html

        1. <!DOCTYPE html>
        2. <html lang="en">
        3. <head>
        4. <meta charset="UTF-8">
        5. <title> My App </title>
        6. <link href="/dist/css/vendor.abf9657f.css" rel="stylesheet">
        7. <link href="/dist/css/index/index.abf9657f.css" rel="stylesheet">
        8. </head>
        9. <body>
        10. <div id="app"></div>
        11. <script type="text/javascript" src="/dist/js/vendor.abf9657f.js"></script>
        12. <script type="text/javascript" src="/dist/js/index/index.abf9657f.js"></script>
        13. </body>
        14. </html>
      • 你会发现相关资源文件都自动引入了,十分便捷。

webpack 常用命令

  • webpack 最基本的启动webpack命令
  • webpack -w 提供watch方法,实时进行打包更新
  • webpack -p 对打包后的文件进行压缩
  • webpack -d 提供SourceMaps,方便调试
  • webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
  • webpack --profile 输出性能数据,可以看到每一步的耗时
  • webpack --display-modules 默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块

webpack dev server

  • 配置示例:

    1. var webpack = require('webpack');
    2. var WebpackDevServer = require('webpack-dev-server');
    3. var config = require('./webpack.config.js');
    4.  
    5. for (var i in config.entry) {
    6. // 每个入口文件加入 client websocket 热加载脚本
    7. config.entry[i].unshift(
    8. "webpack-dev-server/client?http://127.0.0.1:3000/",
    9. "webpack/hot/only-dev-server"
    10. );
    11. }
    12. config.module.loaders.unshift({
    13. test: /\.jsx?$/,
    14. loader: 'react-hot',
    15. exclude: /node_modules/
    16. });
    17. config.plugins.push(new webpack.HotModuleReplacementPlugin());
    18. new WebpackDevServer(webpack(config), {
    19. publicPath: config.output.publicPath,
    20. hot: true,
    21. historyApiFallback: true,
    22. stats: { colors: true }
    23. }).listen(3000, '127.0.0.1', function (err, result) {
    24. if (err) {
    25. console.log(err);
    26. }
    27. console.log('server start');
    28. });
  • 用处

    • 开启服务器调试环境
    • 解决以下两个问题:
      • webpack --watch 打包速度慢
      • 不能做到hot replace
  • 配置

    • Content Base

      • 如果不进行设定的话,服务器伺服默认是在当前目录下。

      • 命令行设置 webpack-dev-server --content-base build/

      • webpack 配置

        1. devServer: {
        2. contentBase: './src/',
        3. historyApiFallback: true,
        4. hot: true,
        5. port: defaultSettings.port,
        6. publicPath: '/assets/',
        7. noInfo: false
        8. }
    • publicPath

      • webpack server 伺服的 bundle 是在内存中的,其相对路径由 publicPath 字段指定。
      • 如果用以上的配置,bundle 可以通过地址 localhost:8080/assets/bundle.js 访问到。(注意:访问的不是output目录下的文件而是内存中的数据!)
  • 自动更新和热替换

    • 配置:

      1. var config = require("./webpack.config.js");
      2. config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
      3. var compiler = webpack(config);
      4. var server = new webpackDevServer(compiler, {
      5. hot: true
      6. ...
      7. });
      8. server.listen(8080);

      关键配置: config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");

      在每个入口文件注入 client websocket 热加载脚本。

webpack 多页面构建的更多相关文章

  1. vue webpack多页面构建

    项目示例地址: https://github.com/ccyinghua/webpack-multipage 项目运行: 下载项目之后 # 下载依赖 npm install # 运行 npm run ...

  2. webpack 多页面支持 & 公共组件单独打包

    webpack - 多页面/入口支持 & 公共组件单独打包 webpack系列目录 webpack 系列 一:模块系统的演进 webpack 系列 二:webpack 介绍&安装 we ...

  3. 使用webpack+vue.js构建前端工程化

    参考文章:https://blog.csdn.net/qq_40208605/article/details/80661572 使用webpack+vue.js构建前端工程化本篇主要介绍三块知识点: ...

  4. 使用Vue和djangoframwork完成登录页面构建 001

    使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ...

  5. webpack多页面应用打包问题-新增页面打包JS影响旧有JS资源

    webpack多页面应用打包问题:如果在项目里新增页面,pages目录中插入一个页面文件,然后打包代码,在webpack3中,新增页面文件上方文件打包出来的JS文件内容全部会改变,点击查看比对,发现问 ...

  6. 完美解决Webpack多页面热加载缓慢问题【转载】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/localhost_1314/article ...

  7. vue-cli + webpack 多页面实例应用

    关于vue.js vue.js是一套构建用户界面的 轻型的渐进式前端框架.它的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.使用vue可以给你的开发带来极致的编程体验. 关于vu ...

  8. webpack 多页面|入口支持和公共组件单独打包--转载

    转载自:http://www.jb51.net/article/117490.htm 本篇主要介绍:如何自动构建入口文件,并生成对应的output:公共js库如何单独打包. 多入口文件,自动扫描入口. ...

  9. webpack前端自动化构建工具

    博主不易,不求赞赏,希望把自己遇到的难点写出来,以及希望自己能有能力写出一篇不错的博文. 前端构建工具本人 bootstrap+jquery用gulp vue+element 用webpack 本人最 ...

随机推荐

  1. 3、Template Method 模板方法 行为型设计模式

    1.了解模板方法 1.1 模式定义 定义一个操作算法中的框架,而将这些步骤延迟加载到子类中. 它的本质就是固定算法框架. 1.2 解决何种问题 让父类控制子类方法的调用顺序 模板方法模式使得子类可以不 ...

  2. 关于GPU你必须知道的基本知识

    图形处理单元(或简称GPU)会负责处理从PC内部传送到所连接显示器的所有内容,无论你在玩游戏.编辑视频或只是盯着桌面的壁纸,所有显示器中显示的图像都是由GPU进行渲染的. 对普通用户来说,实际上不需要 ...

  3. csapp第六章笔记-存储器结构

    目录 随机访问存储器(Random-Access-Memory) 静态RAM 动态RAM 增强的DRAM 非易失性存储器 磁盘存储 磁盘构成 磁盘容量 磁盘操作 逻辑磁盘块 访问磁盘和连接I/O设备 ...

  4. C#LeetCode刷题之#590-N叉树的后序遍历(N-ary Tree Postorder Traversal)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4092 访问. 给定一个 N 叉树,返回其节点值的后序遍历. 例如 ...

  5. 利用BeautifulSoup去除HTML指定标签和去除注释

    去除指定标签 from bs4 import BeautifulSoup #去除属性ul [s.extract() for s in soup("ul")] # 去除属性svg [ ...

  6. axios 常用的几个方法

    Vue推荐使用axios 发送网络请求:最近重新开始做Vue项目,重新回归一下.从axios的几个方法开始吧. 1. 安装: 既然是Vue项目,我还是选择常用的npm的方式 $ npm install ...

  7. 【算法•日更•第五十四期】知识扫盲:什么是operator?

    ▎前言 这个东西和迭代器长的很像,但是比迭代器常见的多. 今天就来浅谈operator. ▎定义 operator是C#.C++和pascal的关键字,它和运算符一起使用,表示一个运算符函数,理解时应 ...

  8. manjaro与python开发环境配置

    1.manjaro配置 1.1.启动项 sudo update-grub 注:Manjaro(archLinux)系统时间快8小时--> sudo timedatectl set-local-r ...

  9. Java 8新特性(一):Lambda表达式

    2014年3月发布的Java 8,有可能是Java版本更新中变化最大的一次.新的Java 8为开发者带来了许多重量级的新特性,包括Lambda表达式,流式数据处理,新的Optional类,新的日期和时 ...

  10. 第一篇 Scrum冲刺博客

    一.Alpha任务认领 冯荣新 任务 预计时间 搜索框 0.5h 首页轮播图 0.5h 分类导航 2h 商品列表 2h 商品详情轮播图 0.5h 商品底部工具栏 1h 购物车列表 1.5h 购物车工具 ...