最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to use both "require" and "import" together with Webpack? - Stac

programmeradmin3浏览0评论

We had to update some dependencies to switch to Webpack 4 and are getting a warning in webpack and an error in the browser when trying to mix import and require within the same project.

We have a very large project (300+ files) with some files using var Pkg = require('./fileName'); and module.exports = MyComponent while others use import Pkg from './fileName' and export default MyComponent and would prefer to not have to go through each one using require/module.exports and update them.

webpack warning:

WARNING in ./index.js 15:17-20
"export 'default' (imported as 'App') was not found in './App.jsx'

browser error:

App.jsx:20 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
    at Module.eval (App.jsx:20)
    at eval (App.jsx:21)
    at Module../App.jsx (bootstrap:83)
    at __webpack_require__ (bootstrap:19)
    at eval (index.js:2)
    at Module../index.js (bootstrap:83)
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

package.json dependency versions:

"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2",

.babelrc

{
  "presets": [
    "@babel/preset-react",
    "@babel/preset-env"
  ]
}

.browserlistrc

{
  "browserslist": [
      ">0.25%",
      "ie 11",
      "not op_mini all"
  ]
}

webpack configs:

rules: [
    {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [{
            loader: 'babel-loader',
            options: {
                babelrc: true
            }
        }],
    },
    // some other rules...   
]

index.js

import App from './App'

// Expose App to the window so we can utilize 
// it from within <script> tags
window.App = App

App.js

import React from 'react'
import ReactDOM from 'react-dom'

var App = (function () {
    return {
        route: function (route, properties) {
            return ReactDOM.render(
                <div>component markup</div>, document.getElementById('workspace')
            )
        }
    }
})()

// This works
// export default App

// This breaks
module.exports = App

index.html

<script>
    App.route('login', {some: 'props'});
</script>

We had to update some dependencies to switch to Webpack 4 and are getting a warning in webpack and an error in the browser when trying to mix import and require within the same project.

We have a very large project (300+ files) with some files using var Pkg = require('./fileName'); and module.exports = MyComponent while others use import Pkg from './fileName' and export default MyComponent and would prefer to not have to go through each one using require/module.exports and update them.

webpack warning:

WARNING in ./index.js 15:17-20
"export 'default' (imported as 'App') was not found in './App.jsx'

browser error:

App.jsx:20 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
    at Module.eval (App.jsx:20)
    at eval (App.jsx:21)
    at Module../App.jsx (bootstrap:83)
    at __webpack_require__ (bootstrap:19)
    at eval (index.js:2)
    at Module../index.js (bootstrap:83)
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

package.json dependency versions:

"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2",

.babelrc

{
  "presets": [
    "@babel/preset-react",
    "@babel/preset-env"
  ]
}

.browserlistrc

{
  "browserslist": [
      ">0.25%",
      "ie 11",
      "not op_mini all"
  ]
}

webpack configs:

rules: [
    {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [{
            loader: 'babel-loader',
            options: {
                babelrc: true
            }
        }],
    },
    // some other rules...   
]

index.js

import App from './App'

// Expose App to the window so we can utilize 
// it from within <script> tags
window.App = App

App.js

import React from 'react'
import ReactDOM from 'react-dom'

var App = (function () {
    return {
        route: function (route, properties) {
            return ReactDOM.render(
                <div>component markup</div>, document.getElementById('workspace')
            )
        }
    }
})()

// This works
// export default App

// This breaks
module.exports = App

index.html

<script>
    App.route('login', {some: 'props'});
</script>
Share Improve this question asked May 9, 2019 at 21:56 adamellsworthadamellsworth 3711 gold badge3 silver badges15 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 17

Technically webpack will bundle (but emit a warning like you see there). However, we at the webpack team suggests that you limit the amount of CommonJS syntax used in your codebase to as small as possible.

Why? Because CommonJS isn't statically analyzable in many edge cases, and therefore "bails out" of optimizations like tree-shaking, and scope-hoisting. This mean's your JavaScript (the most expensive resource on your website to load), will have all sorts of dead/unused code in it.

In our webpack documentation you can observe the listed optimization bailouts and you will notice that one of them is "using CommonJS" or "module" symbols in your code.

Long term this will have significant negative web performance impacts on your application!

If it really is painful to migrate, then I would look into a codemod that will run across your code and transform requires (where possible) to imports!

发布评论

评论列表(0)

  1. 暂无评论