Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack --init default output #119

Closed
addyosmani opened this issue Apr 30, 2017 · 13 comments
Closed

webpack --init default output #119

addyosmani opened this issue Apr 30, 2017 · 13 comments

Comments

@addyosmani
Copy link

addyosmani commented Apr 30, 2017

@ev1stensberg and I were just chatting about the default output of --init. We think it needs to be simple and general enough that most users get value out of using it. Ideally, maintaining a decent performance baseline too.

There are a lot of different configs used by CLIs these days.

  • vue-cli webpack template is very comprehensive. At the same time it feels overkill as the default for --init

  • create-react-app uses these react-scripts Webpack configs under the hood. They're again quite comprehensive, but cater to the needs for a full framework workflow

and of course, Webpack has a comprehensive examples directory over on master.

Should we include:

  • Boilerplate setup for context, entry, output?
  • Automatic vendor bundling?
  • Simplest boilerplate for code-splitting?
  • Performance budgets setup for you?
  • webpack.optimize.UglifyJsPlugin?
  • Should config be split into dev and prod? or kept a single webpack config file?
  • Should loaders for Babel be automatically set up for you? (figure this is common..)
  • Setup ExtractTextPlugin to keep CSS extracted to separate cacheable files?
@FateRiddle
Copy link

  1. One point for 'init' is that you don't have to write the boilerplate of a complete section. Like we can generate things like:
entry: {
     //leave you entry here, or answer the init question next time, like
    //'./src/index.js'    
},
output: {
        path: // './dist',
        filename: //'bundle.js',
        publicPath: 
    }
....

instead of just leave it blank and let user write the whole section.

To me the preferred way is to generate me a 'form', and letting me fill in the blank with some hints.

  1. I prefer one file. So in package.json, people don't need to specify which to use by --config webpack/webpack.config.production.js(which is not obvious to beginners). With the new syntax:
    module.exports = env => { ... } it is possible to write in one file without much redundant code.

  2. Include basic setup for devtools(source-map) and plugin section with webpack.optimize.UglifyJsPlugin, tell people what's it for so they can delete if they don't use it.

  3. ExtractTextPlugin somehow disabled css hot-reload, and for small project, I suppose it doesn't boost performance too much, I'd pass this one for a basic set.

  4. loaders, definitely include babel loader, I can't imagine people don't use import/export want webpack.

  5. Above are for simple webpack init, I'd also love to see a best practice boilerplate for more complicated situations or just for reference how to write certain parts. Maybe webpack --init-all.
    Having a most basic boilerplate is helpful already, but the confusing parts to me are the more complex setups. With good comments, I find no trouble deleting some of them if choose not to use. And it is a good way to show the webpack users what the creator of webpack think is the best practice right now(It is really confusing as webpack doc won't discuss say how to setup for react, and you can find thousands of boilerplate out their but most outdated, and create-react-app is too much a read for me).

@eloytoro
Copy link

eloytoro commented May 1, 2017

I very much think that webpack configs should be factories instead of objects, most people never realize this, but webpack natively supports functions as configs.

In many of my projects I chain up configs so I can separate shared logic among them.

// shared.config.js
export default const ({ minify }) => ({
  plugins: [].concat(
    minify ? [new webpack.optimize.UglifyJsPlugin()] : []
  )
});
// app.config.js
const shared = require('./shared.config');
export default (params) => ({
  ...shared(params);
});

@rossipedia
Copy link
Contributor

rossipedia commented May 1, 2017

Does it need to be --init? Many options can be specified on the command line, so what about having a
--save[=path-to-config.js] option that generates the config file based on the command line parameters?

@opyh
Copy link

opyh commented May 1, 2017

  • Generally I'd be a fan of a structure that resembles an ejected create-react-app (just without the react parts). It's a very sensible start setup for a lot of use cases.
  • How about an interactive command line tool where you can check the recipes that you want? Then I'd take all of the things you mentioned, each as an option ;)
  • Missing: Flowtype support out of the box
  • Also missing: A setup for building components that you can publish as npm modules

@rhmoller
Copy link

rhmoller commented May 1, 2017

Please keep it simple and framework/language agnostic.

It should just write the boilerplate for a webpack config file. It should not change package.json or start installing dependencies. If you want to scaffold a whole application, you can use tools like yeoman, nwb or create-react-app etc.

Optionally it can contain commented out sections with often used fragments along with a brief description.

I like how Typescript have started doing it, though I know a webpack config is much more complicated.

tsc --init will give

{
  "compilerOptions": {
    /* Basic Options */                       
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
    // "lib": [],                             /* Specify library files to be included in the compilation:  */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
                                              
    /* Strict Type-Checking Options */        
    "strict": true                            /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
                                              
    /* Additional Checks */                   
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
                                              
    /* Module Resolution Options */           
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
                                              
    /* Source Map Options */                  
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
                                              
    /* Experimental Options */                
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  }

@evenstensberg
Copy link
Member

Just pushed the initial generator to #105 . Add a shebang to bin/webpack and test it doing webpack-cli --init at that branch. 💯

@ragingwind
Copy link

ragingwind commented May 2, 2017

It should be supported like yarn/npm init because there are some of boilerplates we have to to in most of time as we create a project using webpack. But I hope that it keeps simple. I think the best usecase is yarn init. For rest of boilerplates or configs, it can be provided by supporting as a template, it also could be made from other developers on npms. For example,

// generate a config file for simple usecase with entry, output, dev-server
webpack --init


// this preset has a tons of configuration for Progressive Web App with React
// ex) configs for preload / prefetch, manifest or more ...
npm install -g webpack-init-preset-react-pwa
webpack --init=react-pwa

@RamYadlapalli
Copy link

It would be great if it creates a Webpack configuration file with webpackdev server configuration and Prod configuration

@pramodsvidyarthi
Copy link

An Interactive terminal like Yeoman, which can prompt the users to what loader would they need and configure a webpack.config.json which can serve the development and production configuration.

@chamberlainpi
Copy link

👍 @RamYadlapalli and @pramodsvidyarthi's suggestions.

Was basically going to suggest the same:

It could make the config file a-la "NPM init" style (ie: prompts for the most common settings, entry files, paths, output, loaders + test patterns).

It's true that for frequent VueJS devs though, a preset of somekind would be great. Not sure if Webpack should go in the same direction "Brunch" took with it's "skeletons" (essentially presets / configs), that list of preset could grow exponentially, and a "vuejs" to one person could mean one very different thing from one dev to the next. And personally I don't particularly like referring to a whole / part of a specific Github URL (ex: "user/your-preset-name"), but maybe this is a global config that could associate once, so you basically tell webpack what "vuejs" means to you, and any subsequent "init" uses of it will know where to fetch your favorite preset.

Just some thoughts! Not sure of all of the implications of this.

@ericclemmons
Copy link

I was just thinking about this today as I started a demo project. I'd find the following useful:

  • webpack.config.js has basic named entry, output, and plugins (Define, Uglify).

  • The rest is would be the complete object defaults, but commented out with the docs URL above each section (e.g. devTools).

In a nutshell, I mostly just need to manipulate or uncomment options to successfully get started.

Also, holy crap webpack-dev-server's overlay is cool!

@addyosmani
Copy link
Author

@ericclemmons Perhaps you (and commenters above) could comment on #105 (review) with thoughts on the initial questions Even pitched for the default scaffold? I think it's going to take a few rounds of iterating but open to input :)

@evenstensberg
Copy link
Member

Closing for now, #105 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests