I've gotten into TypeScript and played around with Browserify (with tsify), it worked fine until I switched to Webpack to use vue and babel with my project.
Here is my project structure (simplified, it's also using ASP.NET Core) :
BestAppEver
---| [C# stuff]
---| scripts
---| pages
- Login.ts
- Dashboard.ts
---| components
- CoolThing.vue
- App.ts
- package.json
- webpack.config.js
- tsconfig.json
The files in pages
usually contain jquery declarations like these:
import * as $ from "jquery";
console.log("hi i got loaded!");
$("#deleteConfirmationInput").change(function() {
if (isInputValid()) {
$("#deleteConfirmationButton").removeAttr("disabled");
} else {
$("#deleteConfirmationButton").attr("disabled", "disabled");
}
});
And this is my webpack.config.js
file
var path = require('path');
var webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
entry: './scripts/App.ts',
mode: process.env.NODE_ENV || 'production',
output: {
path: path.resolve(__dirname, 'wwwroot/js'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
]
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
plugins: [
new TsconfigPathsPlugin()
]
}
plugins: [
new VueLoaderPlugin()
],
devtool: 'source-map'
}
if (process.env.NODE_ENV === 'production') {
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
]);
}
With Browserify and tsify, all the files were included and ran, so "hi i got loaded!"
was printed out.
With ts-loader, only the files that i import
ed and used are included and ran. Without importing the file, "hi i got loaded!"
was not printed out. This wasn't the case with .vue
files.
Is there a way to automatically import those files and make them all run in the final bundle?
Thanks :D
The simple answer is exactly what you discovered: you must import the files! Webpack only traverses the file tree starting from the file you name as the entry
(./scripts/App.ts
). Anything else is simply never seen by webpack.
Note that you can use "bare imports" to import the file only for the side effect:
import "./pages/Login.ts";
In this case, you are telling webpack that you don't expect Login.ts
to export anything, but the file should be included in the bundle. You can place these bare imports in your App.ts
.
This question may be relevant: ES6 Bare Import: How to use, and when?
Another option is configuring webpack to use multiple values for entry
. In your case, you should be able to define entry
as an array of strings:
entry: [
'./scripts/App.ts',
'./scripts/Pages/Login.ts',
'./scripts/Pages/Component.ts'
],
If you want to be clever, you can dynamically generate this by recursively listing files in the scripts
directory. webpack.config.js
is just javascript (node) after all. If interested, I can expand the answer to include an example of this.