Laravel-mix: Typescript support

Created on 9 Mar 2017  路  19Comments  路  Source: JeffreyWay/laravel-mix

Hi @JeffreyWay!

Can you explain how to compile .ts with Laravel Mix?

I try follow this issue https://github.com/JeffreyWay/laravel-mix/issues/291#issuecomment-277486760 and here documentation https://github.com/TypeStrong/ts-loader#configuration

// npm install typescript ts-loader

mix
    .webpackConfig({
        module: {
            rules: [
                {
                    test: /\.ts?$/,
                    loader: 'ts-loader'
                }
            ]
        }
    })
    .scripts([
        'resources/assets/js/app.js',
        'resources/assets/ts/defs/*.d.ts',
        'resources/assets/ts/base.ts',
        'resources/assets/ts/models/**/*.ts',
        'resources/assets/ts/starter.ts'
    ], 'public/js/app.js')
    .sass('resources/assets/sass/app.scss', 'public/css');

With this configuration .ts files just combined with all js and not preprocessed. What's wrong?

  • Laravel Mix Version: 0.8.8
  • Node Version (node -v): 7.7.1
  • NPM Version (npm -v): 4.1.2
  • OS: Ubuntu 16.04.1 LTS

Most helpful comment

In case anyone else is interested, I am using typescript in my laravel project and here is the configuration I am using:

package.json:

  ...
  "devDependencies": {
    "laravel-mix": "^0.8.3",
    "ts-loader": "^2.0.2",
    "typescript": "^2.2.1",
    ...
  }

webpack.mix.js:

const { mix } = require('laravel-mix');

mix.webpackConfig({
        resolve: {
            extensions: ['.ts']
        },
        module: {
            rules: [
                {
                    test: /\.ts$/,
                    loader: 'ts-loader'
                }
            ]
        }
    });

mix.js('resources/assets/ts/app.ts', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "isolatedModules": false,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "removeComments": true,
    "suppressImplicitAnyIndexErrors": true,
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "resources/assets/ts/**/*.ts"
  ],
  "compileOnSave": false
}

All 19 comments

mix.scripts() is exclusively for file concatenation. It doesn't run through Webpack. You should use mix.js() instead.

Okay, how we can config compiled files?
It's must be in tsconfig.json?
I replace mix.scripts() to mix.js() and now ts-loader got errors inside vendor folder:

ERROR  Failed to compile with 32 errors
error  in /home/vagrant/Code/project/vendor/symfony/translation/Tests/fixtures/resources.ts

But it's not included in webpack.mix.js

In case anyone else is interested, I am using typescript in my laravel project and here is the configuration I am using:

package.json:

  ...
  "devDependencies": {
    "laravel-mix": "^0.8.3",
    "ts-loader": "^2.0.2",
    "typescript": "^2.2.1",
    ...
  }

webpack.mix.js:

const { mix } = require('laravel-mix');

mix.webpackConfig({
        resolve: {
            extensions: ['.ts']
        },
        module: {
            rules: [
                {
                    test: /\.ts$/,
                    loader: 'ts-loader'
                }
            ]
        }
    });

mix.js('resources/assets/ts/app.ts', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "isolatedModules": false,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "removeComments": true,
    "suppressImplicitAnyIndexErrors": true,
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "resources/assets/ts/**/*.ts"
  ],
  "compileOnSave": false
}

Hi @JeffreyWay wanted to know how angular (typescript) can be mixed with laravel to create a Non-SPA so that the custom components could be used along with blade.

@NoelDeMartin Thanks for the configuration, It works well for me.

Based on @NoelDeMartin solution, all I required was tsconfig.json file and in webpack.mix.js instead of using mix.js, if we use mix.ts then we don't need any extra dependencies to be included nor we need mix.webpackconfig to extend the configuration because using mix.ts, default webpack.config.js file included by node_modules automatically load all dependencies.

Since the release of laravel-mix v1.0.0 typescript is now officially supported.

mix.ts('src/index.ts', 'dist/');

_(mix.ts can transpile both .ts and .tsx files.)_

A tsconfig.json file is required in the same directory as the webpack.mix.js file, and for .tsx it needs to have the property jsx _(within the compilerOptions object)_ set to either react or react-native .

__Example:__

/* webpack.mix.js */
let mix = require('laravel-mix');

mix.ts('src/index.tsx', 'dist/')
    .extract([ 'react' ])
    .sourceMaps()
    .setPublicPath('dist');
/* tsconfig.json */
{
    "lib": [
        "dom",
        "es5",
    ],
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "jsx": "react"
    }
}

@NoelDeMartin Thanks for saving my life!
Besides announced mix.ts() DOES NOT work.
I've asked my friends and none could get it up and running.
How do you perform minification alongside your solution?
I am using .minify('public/assets/js/app.js'), but the output app.min.js doesn't contains the minified file other then some Exceptions exposing my system information.

@gilbertoalbino Could you be more specific about what is failing when using mix.ts? I wrote that comment before that was implemented, now I am using mix.ts and it works just fine.

Minification is performed automatically when running npm run prod, you don't need to configure anything on your mix file for this to happen.

@gilbertoalbino
Firstly, mix.ts() DOES work. What version are you using?
Secondly, if the NODE_ENV environment variable is set to production it will automatically minify the resulting code.

@Olian04 and @NoelDeMartin I figured it out!
The problem itself was kinda weird.

I had some of my packages installed via npm install <PACKAGE> --save-dev, as well as typescriptand ts-loader. I just removed the node_modules folder and run npm install in order to install all the packages automatically and I got it all working and now mix.ts is working.
Somehow before doing that, the solution proposed by @NoelDeMartin worked, but running npm run prod didn't minified the file!

So, after running accross this situation I am encourage to install node packages via package.json file only, and let the installer figure it out itself.

Does this work with TS within single file Vue components?

@eberkund Yes it does.

Sorry to comment on an old Issue.

How can I use TypeScript in _combination_ with .js files? Say if in my resources/assets/js/app.js file I wanted to include some modules that were stored in .ts files?

@martinbean I don't know about importing ts into js (except by importing the compiled js), but the other way around can be solved by setting "allowjs" to true in the tsconfig.
Worth noting, any valid js is valid ts, so you can always change the extension of a js file to ".ts"

@martinbean If I understand correctly, you want to import a .ts file into a .js file? It that's so, there is something you didn't quite understand about Typescript. At the end, .ts files will always be compiled into .js files, so if you are already using laravel-mix (which I guess you are since you are commenting here), you can do one of both:

  • Import that file in your entry point (you'll have an app.ts file which is converted into that app.js file you mention, import there your .ts file).
  • Add this .ts file to your entry files when calling mix.ts() (I think this accepts an array of strings as a first argument, not only one string).

Laravel mix uses webpack and even if you don't want to dig into webpack, I suggest that at least you learn some basic concepts on how dependencies and bundling is handled. When working with webpack, everything is considered a module (images, js, ts, css, etc) and is bundled into one or more files (in this case, app.js). You can start here: https://webpack.js.org/concepts/.

In any case, I don't think this is related with this issue or even laravel-mix, so try to do some google search or post this somewhere more appropriate, like stackoverflow. If you do, try to be more specific about your problem because that seems too broad.

@NoelDeMartin I was wanting to use TypeScript files in the default JavaScript files that come with Laravel (basically nicely-typed, standalone modules). But it sounds like I need to rename my app.js to app.ts and use that as a TypeScript entry point.

Thanks for the pointer!

@martinbean Yes, if you want to use Typescript I recommend you to do everything in TS, and worry about using .js files inside .ts instead. Basically the only thing you need to do is import them and provide typings. Most popular js packages already have ts definitions, and you can find a lot here: https://github.com/DefinitelyTyped/DefinitelyTyped. If you are getting started with typescript it may be a little confusing at the beginning, but it definitely pays off once you get the hang of it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rlewkowicz picture rlewkowicz  路  3Comments

jpriceonline picture jpriceonline  路  3Comments

kpilard picture kpilard  路  3Comments

amin101 picture amin101  路  3Comments

dtheb picture dtheb  路  3Comments