symfony / webpack-encore

A simple but powerful API for processing & compiling assets built around Webpack
https://symfony.com/doc/current/frontend.html
MIT License
2.23k stars 199 forks source link

enableForkedTypeScriptTypesChecking breaks build #1025

Open lebadapetru opened 3 years ago

lebadapetru commented 3 years ago

Adding enableForkedTypeScriptTypesChecking breaks the build and i can't see what i'm missing. enableTypeScriptLoader on its own works perfect

TS2345: Argument of type 'typeof import("/Users/lebadapetrudecebal/Projects/erp/node_modules/vue/dist/vue")' is not assignable to parameter of type 'Component<any, any, any, ComputedOptions, MethodOptions>'.
  Type 'typeof import("/Users/lebadapetrudecebal/Projects/erp/node_modules/vue/dist/vue")' is not assignable to type 'ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any>'.
    Type 'typeof import("/Users/lebadapetrudecebal/Projects/erp/node_modules/vue/dist/vue")' is not assignable to type 'ComponentOptionsBase<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}>'.
      Types of property 'computed' are incompatible.
        Type '{ <T>(getter: ComputedGetter<T>): ComputedRef<T>; <T>(options: WritableComputedOptions<T>): WritableComputedRef<T>; }' is not assignable to type 'ComputedOptions'.
          Index signature is missing in type '{ <T>(getter: ComputedGetter<T>): ComputedRef<T>; <T>(options: WritableComputedOptions<T>): WritableComputedRef<T>; }'.
    10 | import 'element-plus/lib/theme-chalk/index.css';
    11 |
  > 12 | createApp(App)
       |           ^^^
    13 |   .use(store)
    14 |   .use(ElementPlus)
    15 |   .use(router)

main.ts:

import { createApp } from 'vue'
import App from "./App.vue";
import router from "./router";
import store from './store'
import vueClickAway from './assets/js/vendors/plugins/vue-click-away'
import vuePerfectScrollbar from "./assets/js/vendors/plugins/vue-perfect-scrollbar";
import 'bootstrap'
import ElementPlus from 'element-plus';
import 'element-plus/lib/theme-chalk/index.css';

createApp(App)
  .use(store)
  .use(ElementPlus)
  .use(router)
  .use(vueClickAway)
  .use(vuePerfectScrollbar, {
    options: {
      wheelSpeed: 0.3,
      swipeEasing: true,
      wheelPropagation: false,
      minScrollbarLength: 40,
      maxScrollbarLength: 300,
      suppressScrollX: true
    }
  })
  .mount('#app');

webpack.config.js

const Encore = require('@symfony/webpack-encore');
const path = require('path');
//const HtmlWebpackPlugin = require('html-webpack-plugin');

// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
  Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}

Encore
  // directory where compiled assets will be stored
  .setOutputPath('public/build/')
  // public path used by the web server to access the output path
  .setPublicPath('/build')
  // only needed for CDN's or sub-directory deploy
  //.setManifestKeyPrefix('build/')
  .copyFiles({
    from: './resources/assets/media',
    to: 'media/[path][name].[ext]',
    pattern: /\.(png|jpg|jpeg|svg)$/
  })
  .copyFiles({
    from: './resources/assets/fonts',
    to: 'fonts/[path][name].[ext]',
    pattern: /\.(ttf)$/
  })
  /*
   * ENTRY CONFIG
   *
   * Add 1 entry for each "page" of your app
   * (including one that's included on every page - e.g. "app")
   *
   * Each entry will result in one JavaScript file (e.g. main.js)
   * and one CSS file (e.g. app.css) if you JavaScript imports CSS.
   */
  .addEntry('main', './resources/main.ts')
  //.addEntry('page1', './assets/js/page1.js')
  //.addEntry('page2', './assets/js/page2.js')

  // When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
  .splitEntryChunks()

  // will require an extra script tag for runtime.js
  // but, you probably want this, unless you're building a single-page app
  .enableSingleRuntimeChunk()

  /*
   * FEATURE CONFIG
   *
   * Enable & configure other features below. For a full
   * list of features, see:
   * https://symfony.com/doc/current/frontend.html#adding-more-features
   */
  .cleanupOutputBeforeBuild()
  .enableBuildNotifications()
  .enableSourceMaps(!Encore.isProduction())
  // enables hashed filenames (e.g. app.abc123.css)
  .enableVersioning(Encore.isProduction())

  // enables @babel/preset-env polyfills
  .configureBabel(() => {
  }, {
    useBuiltIns: 'usage',
    corejs: 3
  })

  // enables Sass/SCSS support
  .enableSassLoader()

  // enables Vue support
  .enableVueLoader(() => {
  }, {
    version: 3,
    runtimeCompilerBuild: false //if using only single file components, this is not needed (https://symfony.com/doc/current/frontend/encore/vuejs.html#runtime-compiler-build)

  })
  // uncomment if you use TypeScript
  .enableTypeScriptLoader(options => {
    options.appendTsSuffixTo = [/\.vue$/];
  })
  .enableForkedTypeScriptTypesChecking()
  /*.addPlugin(new HtmlWebpackPlugin({
    template: './src/templates/app.html.twig',
  }))*/

  // uncomment if you're having problems with a jQuery plugin
  .autoProvidejQuery()
  .addAliases({
    'resources': path.resolve('./resources')
  })

  /*.addPlugin(
    new webpack.DefinePlugin({
      // Drop Options API from bundle
      __VUE_OPTIONS_API__: false,
      __VUE_PROD_DEVTOOLS__: false
    })
  )*/

// uncomment to get integrity="..." attributes on your script & link tags
// requires WebpackEncoreBundle 1.4 or higher
//.enableIntegrityHashes()

// uncomment if you use API Platform Admin (composer req api-admin)
//.enableReactPreset()
//.addEntry('admin', './assets/js/admin.js')
;

module.exports = Encore.getWebpackConfig();

shims-vue.d.ts :

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "noImplicitThis": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "importHelpers": true,
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    // -------------------------
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ],
    "baseUrl": ".",
    "paths": {
      "resources/*": [
        "resources/*"
      ]
    },
    //"typeRoots": [ "./types", "./node_modules/@types"]
  },
  "files": [
    "shims-vue.d.ts",
  ],
  "include": [
    "resources/**/*.ts",
    "resources/**/*.tsx",
    "resources/**/*.vue",
  ],
  "exclude": [
    "node_modules",
    //"types",
  ]
}

package.json:

{
  "devDependencies": {
    "@symfony/webpack-encore": "^1.5.0",
    "@types/bootstrap": "^5.1.1",
    "@types/jquery": "^3.5.5",
    "@vue/compiler-sfc": "^3.0.2",
    "babel-core": "^7.0.0-bridge.0",
    "file-loader": "^6.0.0",
    "fork-ts-checker-webpack-plugin": "^6.3.2",
    "html-webpack-plugin": "^5.3.2",
    "https-proxy-agent": "^2.2.1",
    "lorem-ipsum": "^2.0.3",
    "sass": "^1.32.13",
    "sass-loader": "^10.2.0",
    "ts-loader": "^8.3.0",
    "tslib": "^2.3.0",
    "vue-loader": "^16.5.0",
    "vue-template-compiler": "^2.6.12",
    "webpack-notifier": "^1.6.0"
  },
  "license": "UNLICENSED",
  "private": true,
  "scripts": {
    "dev-server": "encore dev-server",
    "dev": "encore dev",
    "watch": "encore dev --watch",
    "build": "encore production --progress"
  },
  "dependencies": {
    "@babel/polyfill": "^7.12.1",
    "@ckeditor/ckeditor5-build-classic": "^25.0.0",
    "@fortawesome/fontawesome-free": "^5.15.3",
    "@popperjs/core": "^2.5.4",
    "@tinymce/tinymce-vue": "^4.0.0",
    "@vee-validate/rules": "^4.2.4",
    "@vueform/multiselect": "^2.0.1",
    "axios": "^0.21.1",
    "bootstrap": "^5.0.2",
    "chart.js": "^2.9.4",
    "core-js": "^3.6.5",
    "dropzone": "^5.9.2",
    "element-plus": "^1.0.2-beta.36",
    "es6-promise": "^4.2.8",
    "inputmask": "^5.0.6",
    "jquery": "^3.5.1",
    "lodash": "^4.17.20",
    "nprogress": "^0.2.0",
    "perfect-scrollbar": "^1.5.0",
    "select2": "^4.0.13",
    "sweetalert2": "^11.1.2",
    "typescript": "^4.3.4",
    "vee-validate": "^4.5.0-alpha.2",
    "vue": "^3.0.7",
    "vue-inline-svg": "^3.0.0-beta.2",
    "vue-router": "^4.0.3",
    "vuex": "^4.0.0-rc.1",
    "yup": "^0.29.3"
  }
}
tropicalraisel commented 3 years ago

It would be nice to see your Typescript config file as well. You're also using configureBabel over configureBabelPresetEnv, which indicates that you likely have a custom Babel config too, which would be good to see. Sure deductions can be made from the package.json, but it's nice to see everything, even if you have to create a temporary Github repository that holds the entire project. That method in fact is the most common when actually fixing critical bugs.

A couple pointers on your general configuration:

  1. Leverage configureImageRule and configureFontRule over copying files everywhere. Here's an example.
  2. To organize the package.json, I like to keep packages that are being exported (like Bootstrap, JQuery, and Popper) under dependencies and everything else goes under devDependencies. This increases the overall readability. Ultimately it doesn't really matter, but we have standards on most things for just that reason.
lebadapetru commented 3 years ago

Hey @TropicalRaisel,

I'm not sure why i'm using configureBabel over configureBabelPresetEnv because i have no custom babel config. I believe it was the default setup at that time when i installed encore in my project. Here's the tsconfig:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "noImplicitThis": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ],
    "baseUrl": ".",
    "paths": {
      "resources/*": [
        "resources/*"
      ]
    },
    //"typeRoots": [ "./types", "./node_modules/@types"]
  },
  /*"files": [
    "shims-vue.d.ts",
  ],*/
  "include": [
    "resources/**/*.ts",
    "resources/**/*.tsx",
    "resources/**/*.vue",
  ],
  "exclude": [
    "node_modules",
    //"types",
  ]
}
tropicalraisel commented 3 years ago

That was mislabeld as shims-vue.d.ts. I'd start out by getting the recent Webpack config template, enable all Typescript compatibility, and maintain a basic Typescript config file. Slowly configure compatibility for your project and see if anything breaks, and then you may find the issue. Sometimes there can be packages that share dependencies with different versions that cause problems, so be sure to install only what you need throughout the process. I'd also try changing esnext to es2020, since that's the most modern and common target environment.