Search code examples
typescriptwebpackts-loader

webpack bundle typescript to ts-loader but get module is not defined on browser?


follow webpack typescript doc

when i use webpack ts-loader to convert typescript it's can't work cause module is not defined?

but when i just command tsc, this result can work on browser

also this issues is already use gulp to fix

but gulp use browserify to transform typescript

so i want to use webpack to bundle my express server and client typescript!

why webpack ts-loader to transform typescript get "module is not defined" on browser?

this repositories on github

webpack.config.js

const nodeeExternals = require('webpack-node-externals');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const serverConfig = {
  target: 'node',
  devtool: 'eval-source-map',
  node: {
    __dirname: false,
    __filename: true,
  },
  externals: [nodeExternals()],
  entry: {
    'index': './src/index.js',
    // 'public/javascripts/temibroad': './src/client/typescript/temibroad/temibroad.ts'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js',
    libraryTarget: 'commonjs2',
  },
  module: {   //設定你的檔案選項
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ],
  },
  // plugins: [
  //   new CopyWebpackPlugin([
  //     { from: 'src/client/views', to: 'views' },
  //     { from: 'src/client/static', to: 'public' },
  //   ])
  // ],
  optimization: {
    minimize: true,
  }
}

const clientConfig = {
  target: 'web',
  devtool: 'eval-source-map',
  node: {
    __dirname: false,
    __filename: true,
  },
  externals: [nodeExternals()],
  entry: {
    // 'index': './src/index.js',
    'public/javascripts/temibroad': './src/client/typescript/temibroad/temibroad.ts'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js',
    libraryTarget: 'commonjs2',
  },
  module: {   //設定你的檔案選項
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ],
  },
  plugins: [
    new CopyWebpackPlugin([
      { from: 'src/client/views', to: 'views' },
      { from: 'src/client/static', to: 'public' },
    ])
  ],
  optimization: {
    minimize: true,
  }
}



module.exports = [serverConfig, clientConfig];

tsconfig.json

{
  "compilerOptions": {
  "target": "es5",
  "module": "commonjs",
  "sourceMap": true,
  "noEmitOnError" : false,
  "strict": true,
  "noImplicitAny": true,
  "strictNullChecks": true,
  "esModuleInterop": true,
  "forceConsistentCasingInFileNames": true
  }
}

Solution

  • Mh...i know why got "module is not defined" on browser, cause my output library setting.

    When my project done, then I research webpack doc, step by step check my setting, i find why i setting "commonjs2"(2??) on browser?

    Commonjs can't work on browser immediately, so when i setting libraryTarget to "var", also setting library:'myLibrary' to call TS function, problem is solved.

    Check out the settings below

    /* webpack.config.js : Webpack 的設定檔 */
    // const webpack = require('webpack');
    const path = require('path');
    
    const clientConfig = {
      target: 'web',
      devtool: 'eval-source-map',
      entry: {
        // 'index': './src/index.js',
        'index': './src/index.ts'
      },
      output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].bundle.js',
        library :'aaa',
        libraryTarget: 'var'
      },
      module: {   //設定你的檔案選項
        rules: [
          {
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/,
          },
        ],
      },
      resolve: {
        extensions: [ '.tsx', '.ts', '.js' ],
      },
    }
    
    module.exports = [clientConfig];
    

    index.ts

    import { gogogo } from './import';
    
    
    gogogo();
    
    export { gogogo };
    
    console.log('你好');
    

    import.ts

    function gogogo(str = 'gogogog'){
      console.log(str);
    }
    
    export {gogogo};
    

    index.html

    <script src="./dist/index.bundle.js"></script>
    <script>
      console.log(aaa);
      aaa.gogogo('外面傳入');
    </script>
    

    Browser Console

    gogogog             import.ts?661f:6
    好                  index.ts?71bd:7
    {__esModule: true}  index.html:11 
    外面傳入             import.ts?661f:6
    

    update on 2020/06/30 with require.js

    webpack.config.js

      output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].bundle.js',
        // library :'aaa',
        libraryTarget: 'amd'
      },
    

    index.html

      <script src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js'></script>
      <script>
        require(['./dist/index.bundle'], function(aaa){
          console.log(aaa);
          aaa.gogogo('from aaa');
        })
      </script>