V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cleveryun
V2EX  ›  程序员

想问个 webpack-dev-server/babel 的问题,生成的 js 里目标代码没执行,也没报错

  •  
  •   cleveryun ·
    Yakima-Teng · 2018-04-30 11:33:44 +08:00 · 2889 次点击
    这是一个创建于 2407 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码所在仓库地址: https://github.com/Yakima-Teng/utils-daily/tree/master/examples

    不过我感觉问题主要跟下面贴的这些代码有关,麻烦诸位帮忙看看是不是哪里写错了(现在的问题是能生成目标文件 index.js ,里面也有入口文件 app.js 中的代码console.log($utils),但是在 html 页面引入 index.js 后发现并没有打印出来$utils 变量的值,也没有报错信息):

    webpack 配置:

    // webpack.config.js
    
    module.exports = {
    
      //...other code
    
      entry: fs.readdirSync(__dirname).reduce((entries, dir) => {
        const fullDir = path.join(__dirname, dir)
        const entry = path.join(fullDir, 'app.js')
        // judge whether dir is a directory and whether there is a `app.js` in it in case that it's a directory
        if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) {
          entries[dir] = ['es6-promise/auto', entry]
        }
        return entries
      }, {}),
    
      output: {
        // file built by webpack-dev-server is stored in memory
        path: __dirname,
        filename: '[name]/index.js',
      },
    
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'
          }
        ]
      },
      // .....other code
    }
    
    

    babel 配置(.babelrc ):

    {
      "presets": ["env", "flow"],
      "plugins": []
    }
    

    入口文件之一( app.js ):

    console.log($utils)
    

    生成文件( index.js ,在内存里)太长就不贴了,里面也是有console.log($utils)这句代码的,但是没执行。

    第 1 条附言  ·  2018-04-30 19:24:18 +08:00

    已找到解决办法。使用HtmlWebpackPlugin插件可以解决这个问题。这里简单说下。

    一开始我是打算不用HtmlWebpackPlugin插件,直接手动在html文件里加script标签去引webpack-dev-server在内存里创建的js文件的。

    <script src="index.js">
    

    这时候index.js文件里的内容是这样的:

    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([
      ["basic"],
      {
        "./basic/app.js": (function(module, exports, __webpack_require__) {
          // 这里是编译后的主要代码
          "use strict";
          console.log($utils);
        })
      },
      [
        ["./basic/app.js", "runtime~basic"]
      ]
    ]);
    

    可以看到我们写的代码编译后只是被塞到数组里,而且是作为一个对象key的value,并没有机会被执行。

    但是用了HtmlWebpackPlugin插件后,console.log($utils)这样的代码就直接执行了。这是因为这个插件在生成html并往里面插入<script src="index.js">的同时,还会另外插入另一个运行时js文件:

    <script src="runtime~xxx/index.js">
    <script src="index.js">
    

    这个runtime~xxx/index.js文件里是一段IIFE,里面有这么一段代码:

       var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
       var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
       jsonpArray.push = webpackJsonpCallback;
    

    可以看到,window["webpackJsonp"]这个数组的push方法被重写了,所以console.log('test')的代码才被执行了。

    建议这种情况,还是不要手动去用script引runtime~xxx/???.js这样的文件了,这种命令不是公开api,相关库版本变更后路径、名称是可能会变的,使用知名插件会好一点。

    6 条回复    2018-04-30 19:25:19 +08:00
    oswuhan
        1
    oswuhan  
       2018-04-30 12:34:10 +08:00
    不清楚你的水平,而且我的水平也不高,所以以我的水平来分析这个问题,只能先假设这是一个低级错误:

    出现这个问题的原因会不会是,webpack 打包了你的 esm,但是你并没有 import 并执行这个 esm?
    cleveryun
        2
    cleveryun  
    OP
       2018-04-30 14:22:31 +08:00
    @oswuhan 谢谢回复,我想问的就是怎么可以立即执行-_-。rollup 里可以配 iife、umd 这样直接就执行,webpack 里我需要怎么做呢?
    这里如果我把 app.js 里的内容改成 import 其他的包并且执行,跟现在这样直接写 console.log 应该效果是一样的,应该编译后还是不会执行。
    oswuhan
        3
    oswuhan  
       2018-04-30 16:06:29 +08:00
    你的配置文件我看了一下,感觉问题可能有两点:

    一是,你标题里提到了 webpack-dev-server,但你的 webpack.config.js 并没有 devServer 的相关配置;

    二是,devServer 配置中的 contentBase 字段与 output.publicPath,以及 index.html 文件中的 srcipt 标签的 src 属性值,三者是相关联的,正确配置才能得到你想要的结果。
    cleveryun
        4
    cleveryun  
    OP
       2018-04-30 17:18:06 +08:00
    @oswuhan 加了个 HtmlWebpackPlugin 插件解决掉了,具体原因不知道,原先以为自己手动加 script 标签的话就不用这个插件了,可能这个插件和 webpack4 结合起来起到的效果不只是加个 script 标签的作用。不用这个插件手动 script 引入文件能引入成功,但是编译后的结果跟用了这个插件后自动加的 script 里引入的 js 内容不一样。

    Anyway, 五一快乐😀
    oswuhan
        5
    oswuhan  
       2018-04-30 17:39:43 +08:00
    @cleveryun

    webpac-dev-server 就是内置了一个 express,配合 html-webpack-plugin 使用的话,与你手工创建 html 并引入打包好的 js 文件再用浏览器打开的过程是同等效果的。

    同乐。
    cleveryun
        6
    cleveryun  
    OP
       2018-04-30 19:25:19 +08:00
    @oswuhan 恩,是的,之前我说的有问题。回答我已经追加到问题底部了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2859 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:30 · PVG 20:30 · LAX 04:30 · JFK 07:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.