2

I red this article about creating Angular 2 component library, and it uses inline styles. Is there a way to create a lib without inline styles in Angular 2?

Also I saw this, but there is no word about styles, css.

My problem is, I want to create a complex component with multiple components in it and I use SASS also.

7
  • What do you mean "without inline styles"? Do you mean without styles, or with styles that aren't inline? I'd imagine you could follow the same workflow and use templateUrl and styleUrls with a similar outcome. Commented Jan 9, 2017 at 14:40
  • hi have you tired with webpack and require? Commented Jan 9, 2017 at 14:40
  • 1
    @jonrshape I mean with styles that aren't inline Commented Jan 9, 2017 at 14:41
  • Please provide information about the actual problem you are trying to solve. Why don't you want inline styles? Commented Jan 9, 2017 at 14:41
  • It's possible that they just used inline templates/styles to simplify the examples - did you try using URLs instead in the same workflow? Commented Jan 9, 2017 at 14:44

3 Answers 3

3

The problem here is that when you compile your npm package the styles templates must be inline because when you load it as a npm package you won't be able to achieve the template/css path inside node_modules.

The Angular Material 2 team used the follow gulp task to inline the css and template in its components:

They have created this task file that

  1. Get external CSS and put inline;
  2. Get external Html and put inline;
  3. Removes the module.id from components;

Finally, in the build process they call this task here.

My approach of doing this:

  1. Install gulp, gulp-angular-embed-templates, gulp-inline-ng2-styles.

  2. Create a file called gulpfile.js at the root of your app

  3. add the following code to your gulpfile:

    var gulp = require('gulp');
    var embedTemplates = require('gulp-angular-embed-templates');
    var inlineNg2Styles = require('gulp-inline-ng2-styles');
    
    gulp.task('js:build', function () {
      gulp.src('src/*.ts') // also can use *.js files
        .pipe(embedTemplates({sourceType:'ts'}))
        .pipe(inlineNg2Styles({ base: '/src' }))
        .pipe(gulp.dest('./dist'));
    });
    
  4. run gulp js:build;

  5. run npm run build;

After that you will have a dist folder with a component containing your styles and template inline.

First answer (Does not solve the problem)

Just use styleUrls instead styles. Also works for template, just use templateUrl instead template:

@Component({
    selector: 'hello-world',
    styleUrls: ['./hello-world.component.scss'], // HERE (OR CSS)
    templateUrl: './hello-world.component.html', // THE SAME FOR TEMPLATE
})
export class HelloWorld {
    ...
}

Don't forget to create the new files with the styles and template (./hello-world.component.scss and ./hello-world.component.html).

Sign up to request clarification or add additional context in comments.

6 Comments

By creating .html and .scss you mean to copy from the source?
Yes. Remove from component declaration and put ir inside the respective files... like /app/hello-world/hello-world.component.htmland /app/hello-world/hello-world.component.css
I don't know if you understand, I want to create a library, that I can use in an other project
I did. When you load this component in another one, the styles are loaded too based on styleUrls. What happens when you change the inline style to an external one?
The link to the Angular team's file is broken. Is there another place to look at that?
|
2

I use sass for all my components. If you use Webpack install sass-loader add:

loaders: [
             {
                 test: /\.scss$/,
                 exclude: /node_modules/,
                 loader: 'style-loader!css-loader!sass-loader'
              }
         ],

and then in your component specify your components scss file

@Component({
    selector: 'test',
    templateUrl: './test.template.html',
    styleUrls: ['./test.styles.scss']
})

Then you can use sass external files for all your components.

Also if you need some global styles or want import a theme add this to your top level component. This is good for adding bootstrap to your app or some global styles your components might need to share:

@Component({
    selector: 'app',
    encapsulation: ViewEncapsulation.None,
    templateUrl: './app.template.html',
    styleUrls: [
        '../assets/scss/bootstrap.scss',
        './app.style.scss'
    ]
})

Comments

1

If you want to use external HTML templates and CSS styles (or even SCSS styles) you might inline them first before NGC compilation by using Gulp and 'gulp-inline-ng2-template' plugin.

Angular library build workflow with external SCSS and HTML tempaltes

Here is how you npm scripts may look like in package.json:

{
  "scripts": {
    ...
    "build:esm": "gulp inline-templates && npm run ngcompile",
    "ngcompile": "node_modules/.bin/ngc -p tsconfig-aot.json",
    ...
  }
}

Then gulpfile.js would look like.

const gulp = require('gulp');
const sass = require('node-sass');
const inlineTemplates = require('gulp-inline-ng2-template');

/**
 * Inline templates configuration.
 * @see  https://github.com/ludohenin/gulp-inline-ng2-template
 */
const INLINE_TEMPLATES = {
  SRC: './src/**/*.ts',
  DIST: './tmp/src-inlined',
  CONFIG: {
    base: '/src',
    target: 'es6',
    useRelativePaths: true,
    styleProcessor: compileSass
  }
};

/**
 * Inline external HTML and SCSS templates into Angular component files.
 * @see: https://github.com/ludohenin/gulp-inline-ng2-template
 */
gulp.task('inline-templates', () => {
  return gulp.src(INLINE_TEMPLATES.SRC)
    .pipe(inlineTemplates(INLINE_TEMPLATES.CONFIG))
    .pipe(gulp.dest(INLINE_TEMPLATES.DIST));
});


/**
 * Compile SASS to CSS.
 * @see https://github.com/ludohenin/gulp-inline-ng2-template
 * @see https://github.com/sass/node-sass
 */
function compileSass(path, ext, file, callback) {
  let compiledCss = sass.renderSync({
    data: file,
    outputStyle: 'compressed',
  });
  callback(null, compiledCss.css);
}

This approach is utilized by angular-library-seed. You may look there for full integration example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.