【问题标题】:Local video will not load - Webpack本地视频无法加载 - Webpack
【发布时间】:2017-12-23 00:58:47
【问题描述】:

我无法加载/播放简单的视频,所以我决定尝试查看 webpack 文件,它看起来不错。代码如下。

const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');

const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const host = process.env.HOST || '0.0.0.0';
const port = parseInt(process.env.PORT, 10) || 3000;
const publicPath = `${protocol}://${host}:${port}/`;

const publicUrl = '';
const env = getClientEnvironment(publicUrl);

module.exports = {
    devtool: 'cheap-module-source-map',
    entry: [
        require.resolve('./polyfills'),
        require.resolve('webpack-dev-server/client') + `?${publicPath}`,
        require.resolve('webpack/hot/dev-server'),
        paths.appIndexJs,
    ],
    output: {
        pathinfo: true,
        filename: 'static/js/bundle.js',
        chunkFilename: 'static/js/[name].chunk.js',
        publicPath: publicPath,
        devtoolModuleFilenameTemplate: info =>
            path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
    },
    resolve: {
        modules: ['node_modules', paths.appNodeModules].concat(
            process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
        ),
        extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
        alias: {
            'react-native': 'react-native-web',
        },
        plugins: [
            new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
        ],
    },
    module: {
        strictExportPresence: true,
        rules: [
            {
                test: /\.(js|jsx|mjs)$/,
                enforce: 'pre',
                use: [
                    {
                        options: {
                            formatter: eslintFormatter,
                            eslintPath: require.resolve('eslint'),  
                        },
                        loader: require.resolve('eslint-loader'),
                    },
                ],
                include: paths.appSrc,
            },
            {
                oneOf: [
                    {
                        test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                        loader: require.resolve('url-loader'),
                        options: {
                            limit: 10000,
                            name: 'static/media/[name].[hash:8].[ext]',
                        },
                    },
                    {
                        test: /\.(js|jsx|mjs)$/,
                        include: paths.appSrc,
                        loader: require.resolve('babel-loader'),
                        options: {
                            cacheDirectory: true,
                        },
                    },
                    {
                        test: /\.css$/,
                        use: [
                            require.resolve('style-loader'),
                            {
                                loader: require.resolve('css-loader'),
                                options: {
                                    importLoaders: 1,
                                },
                            },
                            {
                                loader: require.resolve('postcss-loader'),
                                options: {
                                    ident: 'postcss',
                                    plugins: () => [
                                        require('postcss-flexbugs-fixes'),
                                        autoprefixer({
                                            browsers: [
                                                '>1%',
                                                'last 4 versions',
                                                'Firefox ESR',
                                                'not ie < 9', // React doesn't support IE8 anyway
                                            ],
                                            flexbox: 'no-2009',
                                        }),
                                    ],
                                },
                            },
                        ],
                    },
                    {
                        test: /\.(html)$/,
                        loader: require.resolve('html-loader'),
                    },
                    {
                        test: /\.mp4$/,
                        use: [
                            {
                                loader: require.resolve('file-loader'),
                                options: {
                                    name: 'static/media/[name].[hash:8].[ext]'
                                }  
                            }
                        ]
                    },
                    {
                        exclude: [/\.js$/, /\.html$/, /\.json$/],
                        loader: require.resolve('file-loader'),
                        options: {
                            name: 'static/media/[name].[hash:8].[ext]',
                        },
                    },
                ],
            },
        ],
    },
    plugins: [
        new InterpolateHtmlPlugin(env.raw),
        new HtmlWebpackPlugin({
            inject: true,
            template: paths.appHtml,
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.DefinePlugin(env.stringified),
        new webpack.HotModuleReplacementPlugin(),
        new CaseSensitivePathsPlugin(),
        new WatchMissingNodeModulesPlugin(paths.appNodeModules),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    ],
    node: {
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty',
    },
    performance: {
        hints: false,
    },
    target: 'node-webkit',
};

这是我的 App.js 下面。我把所有无关紧要的东西都拿出来了。这是对 mp4 文件的简单调用。

import React, { Component } from 'react';
import { curious } from '@curi/react';
import AttractLoop from '../../assets/videos/video.mp4';

class App extends Component {
    render() {
        return (
            <div className="app-container">
                <div className="attract-loop">
                    <video width="1080" height="1920">
                        <source src={ AttractLoop } type="video/mp4" />
                    </video>
                </div>
            </div>
        );
    }
}

export default curious(App);

这是我的代码检查器的屏幕截图:

更新 1

我什至在尝试使用来自 SO question 的代码:

<video width="1080" height="1920" autoPlay loop src={ AttractLoop } type="video/mp4" />

更新 2

我下载了示例Big Buck Bunny video 以排除我的视频编码错误。得到相同的结果,一个空白页。

【问题讨论】:

  • 我的第一个猜测是放弃static。我认为这是您的output.publicPathoutput.path 的一部分,所以您不需要它。然而,这完全是在黑暗中拍摄的。很难在没有看到其余设置的情况下准确地说出。如果这不是问题,您能否分享您的 webpack.config.js 的其余部分?
  • 编辑问题以包含整个文件
  • 嗯,您的配置乍一看还不错。你能帮我检查两件事吗?首先,确保在你运行 webpack 之后,mp4 文件实际输出到你的static/media 目录。其次,打开你的包(如果你在 Windows 上,我推荐 Notepad++,因为它可以很好地处理大文件)并搜索该 mp4 文件的名称。如果没有足够的信息来解决这个问题,请在此处分享该代码块。
  • 我在 bundle.js 中看不到 mp4。我将它导入到我的班级,如下所示:import carHomeToTopVideo from '../../assets/videos/_view_home_to_top.mp4';,正确的 url 显示在视频标签中,显示为localhost:3000/static/media/_view_home_to_top.mp4。如果我从检查器中获取 localhost 链接并将其直接放在浏览器中,视频就会播放。有什么想法吗?
  • 我添加了调用我的视频文件的代码。我尝试在我的开发机器上注释掉所有内容,并获得了最简单的页面形式......一个应该在加载时运行的静态视频文件,我只看到视频的容器,但看不到视频。没有开发工具错误或任何警告。

标签: javascript reactjs webpack create-react-app


【解决方案1】:

我想给出真正问题的答案,尽管 @Jonny 有一些很好的 webpack 更改应该可以帮助其他人。

My Create React App 与 Nw.js 混合使用,Nw.js 是一个允许用户从他们的项目创建 exe 文件的平台。我从https://github.com/naviapps/create-nw-react-app/issues/6 发现 NW.js 默认不允许 mp4,因此我需要配置我的项目设置以接受它们或将我的视频格式更改为 ogv(或其他)。

【讨论】:

    【解决方案2】:

    这里的问题是您的webpack.config.js 设置为将您的媒体输出到静态目录。使用 ExpressJS,您定义的静态目录不应在公共路径中使用。该路径映射到您的公共路径的根目录。要解决此问题,您需要调整 webpack.config.js 以仍输出到此静态目录,但在使用文件加载器加载文件时不要将其写入文件名。试试这样的:

    module.exports = {
      devtool: 'cheap-module-source-map',
      entry: [
        require.resolve('./polyfills'),
        require.resolve('webpack-dev-server/client') + `?${publicPath}`,
        require.resolve('webpack/hot/dev-server'),
        paths.appIndexJs,
      ],
      output: {
        pathinfo: true,
        filename: 'js/bundle.js',
        chunkFilename: 'js/[name].chunk.js',
        // double check that this has it's backslashes in the right place
        path: path.resolve(__dirname, publicPath + '/static'),
        publicPath: publicPath',
        devtoolModuleFilenameTemplate: info =>
          path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
      },
      resolve: {
        modules: ['node_modules', paths.appNodeModules].concat(
          process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
        ),
        extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
        alias: {
          'react-native': 'react-native-web',
        },
        plugins: [
          new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
        ],
      },
      module: {
        strictExportPresence: true,
        rules: [
          {
            test: /\.(js|jsx|mjs)$/,
            enforce: 'pre',
            use: [
              {
                options: {
                  formatter: eslintFormatter,
                  eslintPath: require.resolve('eslint'),
                },
                loader: require.resolve('eslint-loader'),
              },
            ],
            include: paths.appSrc,
          },
          {
            oneOf: [
              {
                test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                loader: require.resolve('url-loader'),
                options: {
                  limit: 10000,
                  //name: 'static/media/[name].[hash:8].[ext]',
                  name: 'media/[name].[hash:8].[ext]',
                },
              },
              {
                test: /\.(js|jsx|mjs)$/,
                include: paths.appSrc,
                loader: require.resolve('babel-loader'),
                options: {
                  cacheDirectory: true,
                },
              },
              {
                test: /\.css$/,
                use: [
                  require.resolve('style-loader'),
                  {
                    loader: require.resolve('css-loader'),
                    options: {
                      importLoaders: 1,
                    },
                  },
                  {
                    loader: require.resolve('postcss-loader'),
                    options: {
                      ident: 'postcss',
                      plugins: () => [
                        require('postcss-flexbugs-fixes'),
                        autoprefixer({
                          browsers: [
                            '>1%',
                            'last 4 versions',
                            'Firefox ESR',
                            'not ie < 9', // React doesn't support IE8 anyway
                          ],
                          flexbox: 'no-2009',
                        }),
                      ],
                    },
                  },
                ],
              },
              {
                test: /\.(html)$/,
                loader: require.resolve('html-loader'),
              },
              {
                test: /\.mp4$/,
                use: [
                  {
                    loader: require.resolve('file-loader'),
                    options: {
                      //name: 'static/media/[name].[hash:8].[ext]'
                      name: 'media/[name].[hash:8].[ext]'
                    }
                  }
                ]
              },
              {
                exclude: [/\.js$/, /\.html$/, /\.json$/],
                loader: require.resolve('file-loader'),
                options: {
                  //name: 'static/media/[name].[hash:8].[ext]',
                  name: 'media/[name].[hash:8].[ext]',
                },
              },
            ],
          },
        ],
      },
      plugins: [
        new InterpolateHtmlPlugin(env.raw),
        new HtmlWebpackPlugin({
          inject: true,
          template: paths.appHtml,
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.DefinePlugin(env.stringified),
        new webpack.HotModuleReplacementPlugin(),
        new CaseSensitivePathsPlugin(),
        new WatchMissingNodeModulesPlugin(paths.appNodeModules),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      ],
      node: {
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty',
      },
      performance: {
        hints: false,
      },
      target: 'node-webkit',
    };
    

    【讨论】:

    • 我无法让它工作。添加更改(取出静态并添加输出路径)只是使服务器中断。但这确实让我更加深入。 webpackDevServer 和这个有什么关系吗?
    • 你的配置可能有问题——我个人不使用 webpack-dev-server 并且更愿意远离它,但那里可能存在问题。基本上,您需要确保发生一些事情: 1. 您的资产输出到您期望的目录。 2. 该目录由您的服务器公开/静态。 3. 您的代码引用了指向该公共/静态目录的正确 url。你有没有可能把它修剪下来并在 github 上分享(这样我就可以承诺它来显示差异)?如果有帮助,我不介意仔细查看我的环境。
    • 我很乐意并且非常感谢您的帮助!我有很多代码,所以最简单的方法可能是安装 Create NW React App (github.com/naviapps/create-nw-react-app),将其弹出,然后下载 Big Buck Bunny 视频 (camendesign.com/code/video_for_everybody/test.html),将其放置在本地,然后使用上面的代码拨打App.js上的视频。在遇到问题之前我没有接触过配置文件,所以一切都类似于全新安装。
    • hmmm -- 看起来 create-nw-react-app 不是 linux 兼容的 :( 认为你可以启动一个,弹出它,然后把它扔到 github 上?
    • 感谢您在这方面真正帮助我!我最终得到了真正的答案,但我相信你的答案可以帮助可能遇到 webpack 问题的其他人,这就是你获得赏金的原因。我从项目的 github 得到了真正的答案。显然,Nw.js(与 Create React App 混合使用)默认情况下不允许 mp4,因此我需要对其进行配置或将我的视频格式更改为 ogv。 github.com/naviapps/create-nw-react-app/issues/6
    猜你喜欢
    • 2017-04-05
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2017-06-18
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多